@ngutil/floating 0.0.51 → 0.0.53
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/esm2022/floating/floating-ref.mjs +18 -14
- package/esm2022/floating/traits/animation.mjs +70 -15
- package/esm2022/floating/traits/backdrop.mjs +7 -41
- package/esm2022/floating/traits/close-trigger.mjs +86 -0
- package/esm2022/floating/traits/dim-contraint.mjs +4 -4
- package/esm2022/floating/traits/index.mjs +2 -2
- package/esm2022/floating/traits/modal.mjs +5 -5
- package/esm2022/floating/traits/position-calc.mjs +27 -9
- package/esm2022/floating/traits/position.mjs +16 -3
- package/esm2022/layer/backdrop-ref.mjs +15 -35
- package/esm2022/layer/layer.service.mjs +5 -4
- package/fesm2022/ngutil-floating.mjs +239 -134
- package/fesm2022/ngutil-floating.mjs.map +1 -1
- package/floating/floating-ref.d.ts +6 -1
- package/floating/traits/animation.d.ts +7 -4
- package/floating/traits/backdrop.d.ts +7 -12
- package/floating/traits/close-trigger.d.ts +35 -0
- package/floating/traits/index.d.ts +1 -1
- package/floating/traits/modal.d.ts +5 -4
- package/floating/traits/position-calc.d.ts +13 -11
- package/layer/backdrop-ref.d.ts +7 -22
- package/layer/layer.service.d.ts +1 -1
- package/package.json +4 -4
- package/esm2022/floating/traits/keystroke.mjs +0 -17
- package/floating/traits/keystroke.d.ts +0 -8
|
@@ -1,32 +1,56 @@
|
|
|
1
1
|
import { AnimationBuilder, style as style$1, animate } from '@angular/animations';
|
|
2
|
-
import { Observable, tap,
|
|
2
|
+
import { Observable, switchMap, tap, timer, take, map, fromEvent, filter, from, of, race, finalize, exhaustMap, distinctUntilChanged, combineLatest, takeUntil, share, ReplaySubject, shareReplay, takeWhile, debounceTime, startWith, EMPTY } from 'rxjs';
|
|
3
3
|
import { animationObservable, CoverService } from '@ngutil/graphics';
|
|
4
|
-
import { Duration, Ease, DimensionWatcher, rectExpand, rectOrigin, rectMoveOrigin, rectContract, RectWatcher } from '@ngutil/style';
|
|
4
|
+
import { Duration, Ease, alignmentToTransformOrigin, DimensionWatcher, rectExpand, rectOrigin, rectMoveOrigin, rectContract, alignmentNormalize, RectWatcher } from '@ngutil/style';
|
|
5
|
+
import { KeystrokeService, FocusService } from '@ngutil/aria';
|
|
6
|
+
import { coerceElement, isElementInput, Lifecycle, toSorted } from '@ngutil/common';
|
|
5
7
|
import { clamp } from 'lodash';
|
|
6
|
-
import { isElementInput, Lifecycle, toSorted } from '@ngutil/common';
|
|
7
|
-
import { FocusService, KeystrokeService } from '@ngutil/aria';
|
|
8
8
|
import * as i0 from '@angular/core';
|
|
9
9
|
import { ElementRef, Injector, ComponentFactoryResolver, ViewContainerRef, InjectionToken, inject, Directive, Inject, Optional, Injectable, TemplateRef, NgModule } from '@angular/core';
|
|
10
10
|
import { DomPortalOutlet, ComponentPortal, TemplatePortal } from '@angular/cdk/portal';
|
|
11
11
|
|
|
12
12
|
// https://tympanus.net/Development/ModalWindowEffects/
|
|
13
|
-
const
|
|
13
|
+
const timing = `${Duration.FastMs}ms ${Ease.Deceleration}`;
|
|
14
14
|
class AnimationTrait {
|
|
15
|
-
constructor(animation) {
|
|
15
|
+
constructor(animation, options) {
|
|
16
16
|
this.animation = animation;
|
|
17
|
+
this.options = options;
|
|
17
18
|
this.name = "animation";
|
|
18
19
|
}
|
|
19
20
|
connect(floatingRef) {
|
|
20
21
|
return new Observable((dst) => {
|
|
21
22
|
const builder = floatingRef.container.injector.get(AnimationBuilder);
|
|
22
23
|
const element = floatingRef.container.nativeElement;
|
|
23
|
-
|
|
24
|
-
floatingRef.state.on("
|
|
24
|
+
const options = this.options || {};
|
|
25
|
+
floatingRef.state.on("showing", () => animationParams(floatingRef, 0, options.params).pipe(switchMap(params => animationObservable({
|
|
26
|
+
builder,
|
|
27
|
+
element,
|
|
28
|
+
animation: this.animation.show,
|
|
29
|
+
options: { ...options, params }
|
|
30
|
+
}))));
|
|
31
|
+
floatingRef.state.on("disposing", () => animationParams(floatingRef, 0, options.params).pipe(switchMap(params => animationObservable({
|
|
32
|
+
builder,
|
|
33
|
+
element,
|
|
34
|
+
animation: this.animation.hide,
|
|
35
|
+
options: { ...options, params }
|
|
36
|
+
})), tap(() => (element.style.display = "none"))));
|
|
25
37
|
floatingRef.state.on("disposing", () => dst.complete());
|
|
26
38
|
dst.next();
|
|
27
39
|
});
|
|
28
40
|
}
|
|
29
41
|
}
|
|
42
|
+
function animationParams(floatingRef, delay, overrides) {
|
|
43
|
+
const src = delay > 0
|
|
44
|
+
? timer(delay).pipe(switchMap(() => floatingRef.watchTrait("position")))
|
|
45
|
+
: floatingRef.watchTrait("position");
|
|
46
|
+
return src.pipe(take(1), map(position => {
|
|
47
|
+
const origin = position.computed ? alignmentToTransformOrigin(position.computed.content.align) : "center";
|
|
48
|
+
return {
|
|
49
|
+
origin,
|
|
50
|
+
...overrides
|
|
51
|
+
};
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
30
54
|
const FallAnimation = {
|
|
31
55
|
show: [
|
|
32
56
|
style$1({
|
|
@@ -34,35 +58,61 @@ const FallAnimation = {
|
|
|
34
58
|
visibility: "visible",
|
|
35
59
|
opacity: "0"
|
|
36
60
|
}),
|
|
37
|
-
animate(
|
|
61
|
+
animate(timing, style$1({
|
|
38
62
|
transform: "scale(1)",
|
|
39
63
|
opacity: "1"
|
|
40
64
|
}))
|
|
41
65
|
],
|
|
42
66
|
hide: [
|
|
43
|
-
animate(
|
|
67
|
+
animate(timing, style$1({
|
|
44
68
|
transform: "scale(1.5)",
|
|
45
69
|
visibility: "visible",
|
|
46
70
|
opacity: "0"
|
|
47
71
|
}))
|
|
48
72
|
]
|
|
49
73
|
};
|
|
50
|
-
function fallAnimation() {
|
|
51
|
-
return new AnimationTrait(FallAnimation);
|
|
74
|
+
function fallAnimation(options) {
|
|
75
|
+
return new AnimationTrait(FallAnimation, options);
|
|
52
76
|
}
|
|
53
77
|
const FadeAnimation = {
|
|
54
|
-
show: [style$1({ opacity: 0 }), animate(
|
|
55
|
-
hide: [animate(
|
|
78
|
+
show: [style$1({ opacity: 0 }), animate(timing, style$1({ opacity: 1 }))],
|
|
79
|
+
hide: [animate(timing, style$1({ opacity: 0 }))]
|
|
56
80
|
};
|
|
57
|
-
function fadeAnimation() {
|
|
58
|
-
return new AnimationTrait(FadeAnimation);
|
|
81
|
+
function fadeAnimation(options) {
|
|
82
|
+
return new AnimationTrait(FadeAnimation, options);
|
|
59
83
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
84
|
+
const DropAnimation = {
|
|
85
|
+
show: [
|
|
86
|
+
style$1({
|
|
87
|
+
transform: "translate({{ translateX }}, {{ translateY }})",
|
|
88
|
+
opacity: "0",
|
|
89
|
+
transformOrigin: "{{ origin }}",
|
|
90
|
+
visibility: "visible"
|
|
91
|
+
}),
|
|
92
|
+
animate(timing, style$1({
|
|
93
|
+
opacity: "1",
|
|
94
|
+
transform: "scale(1, 1) translate(0px, 0px)"
|
|
95
|
+
}))
|
|
96
|
+
],
|
|
97
|
+
hide: [
|
|
98
|
+
animate(timing, style$1({ opacity: 0, transform: "translate(calc({{ translateX }} * -1), calc({{ translateY }} * -1))" }))
|
|
99
|
+
]
|
|
100
|
+
};
|
|
101
|
+
function dropAnimation(options) {
|
|
102
|
+
if (!options) {
|
|
103
|
+
options = {};
|
|
104
|
+
}
|
|
105
|
+
if (!options.params) {
|
|
106
|
+
options.params = {};
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
options.params = { ...options.params };
|
|
64
110
|
}
|
|
111
|
+
options.params["translateX"] = "0px";
|
|
112
|
+
options.params["translateY"] = "-40px";
|
|
113
|
+
return new AnimationTrait(DropAnimation, options);
|
|
65
114
|
}
|
|
115
|
+
|
|
66
116
|
class BackdropTrait {
|
|
67
117
|
constructor(options) {
|
|
68
118
|
this.options = options;
|
|
@@ -71,24 +121,10 @@ class BackdropTrait {
|
|
|
71
121
|
connect(floatingRef) {
|
|
72
122
|
return new Observable((dest) => {
|
|
73
123
|
const animationBuilder = floatingRef.container.injector.get(AnimationBuilder);
|
|
74
|
-
const options = {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
style: this.options.style
|
|
79
|
-
};
|
|
80
|
-
if (this.options.type === "crop") {
|
|
81
|
-
;
|
|
82
|
-
options.crop = floatingRef
|
|
83
|
-
.watchTrait("position")
|
|
84
|
-
.pipe(map(position => position.anchor));
|
|
85
|
-
}
|
|
86
|
-
const state = new BackdropState();
|
|
87
|
-
const backdrop = floatingRef.layerSvc.newBackdrop(options);
|
|
88
|
-
if (this.options.closeOnClick) {
|
|
89
|
-
dest.add(this.#installClickHandler(floatingRef, backdrop, state));
|
|
90
|
-
dest.add(state.onClick.pipe(exhaustMap(() => floatingRef.close())).subscribe());
|
|
91
|
-
}
|
|
124
|
+
const options = { ...this.options };
|
|
125
|
+
const backdrop = floatingRef.layerSvc.newBackdrop(floatingRef.container, options);
|
|
126
|
+
floatingRef.container.nativeElement.setAttribute("data-floating-has-backdrop", "true");
|
|
127
|
+
backdrop.nativeElement.setAttribute("data-floating-backdrop", floatingRef.uid);
|
|
92
128
|
backdrop.state.on("showing", () => animationObservable({
|
|
93
129
|
builder: animationBuilder,
|
|
94
130
|
element: backdrop.nativeElement,
|
|
@@ -102,29 +138,97 @@ class BackdropTrait {
|
|
|
102
138
|
backdrop.state.on("disposed", () => dest.complete());
|
|
103
139
|
floatingRef.state.on("disposing", () => backdrop.dispose());
|
|
104
140
|
dest.add(backdrop.show().subscribe());
|
|
105
|
-
dest.next(
|
|
141
|
+
dest.next(backdrop);
|
|
106
142
|
});
|
|
107
143
|
}
|
|
108
|
-
#installClickHandler(floatingRef, backdrop, state) {
|
|
109
|
-
const handler = (event) => {
|
|
110
|
-
if (event.defaultPrevented) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
if (event.target === backdrop.nativeElement || backdrop.nativeElement.contains(event.target)) {
|
|
114
|
-
;
|
|
115
|
-
state.onClick.next();
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
document.addEventListener("click", handler);
|
|
119
|
-
return () => {
|
|
120
|
-
document.removeEventListener("click", handler);
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
144
|
}
|
|
124
145
|
function backdrop(options) {
|
|
125
146
|
return new BackdropTrait(options);
|
|
126
147
|
}
|
|
127
148
|
|
|
149
|
+
class CloseTriggerTrait {
|
|
150
|
+
constructor(options = {}) {
|
|
151
|
+
this.options = options;
|
|
152
|
+
this.name = "close-trigger";
|
|
153
|
+
}
|
|
154
|
+
connect(floatingRef) {
|
|
155
|
+
const { keystroke, clickOutside, trigger } = this.options;
|
|
156
|
+
const container = floatingRef.container.nativeElement;
|
|
157
|
+
const triggers = [];
|
|
158
|
+
const selfUid = Number(floatingRef.uid);
|
|
159
|
+
if (keystroke) {
|
|
160
|
+
const ks = floatingRef.container.injector.get(KeystrokeService);
|
|
161
|
+
triggers.push(ks.watch(container, { key: "Escape", state: "up" }).pipe(map(() => {
|
|
162
|
+
return { source: "keystroke" };
|
|
163
|
+
})));
|
|
164
|
+
// TODO: angular auxiliary route
|
|
165
|
+
}
|
|
166
|
+
if (clickOutside) {
|
|
167
|
+
const allowedElements = typeof clickOutside === "boolean" ? [] : clickOutside.allowedElements?.map(coerceElement) || [];
|
|
168
|
+
triggers.push(fromEvent(document, "click", { capture: true, passive: true }).pipe(filter(event => {
|
|
169
|
+
if (!(event.target instanceof HTMLElement)) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
const target = event.target;
|
|
173
|
+
for (const allowed of allowedElements) {
|
|
174
|
+
if (target === allowed || allowed.contains(target)) {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const floatingUid = getFloatingUid(target, "data-floating", "floating");
|
|
179
|
+
const backdropUid = getFloatingUid(target, "data-floating-backdrop", "floatingBackdrop");
|
|
180
|
+
const otherBackdropUid = floatingUid != null && floatingUid !== selfUid
|
|
181
|
+
? getFloatingUid(document.querySelector(`[data-floating-backdrop="${floatingUid}"]`), "data-floating-backdrop", "floatingBackdrop")
|
|
182
|
+
: undefined;
|
|
183
|
+
// console.log({ floatingUid, backdropUid, otherBackdropUid, self: selfUid })
|
|
184
|
+
if (floatingUid == null && backdropUid == null) {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
return (
|
|
189
|
+
// click on self backdrop
|
|
190
|
+
(backdropUid != null && backdropUid === selfUid) ||
|
|
191
|
+
// click on other floating element, whitout backdrop
|
|
192
|
+
(floatingUid != null && otherBackdropUid == null && floatingUid !== selfUid) ||
|
|
193
|
+
// click on other floating element that opened erlier
|
|
194
|
+
(floatingUid != null && floatingUid < selfUid));
|
|
195
|
+
}
|
|
196
|
+
}), map(() => {
|
|
197
|
+
return { source: "click" };
|
|
198
|
+
})));
|
|
199
|
+
}
|
|
200
|
+
if (trigger) {
|
|
201
|
+
triggers.push(from(trigger).pipe(map(() => {
|
|
202
|
+
return { source: "trigger" };
|
|
203
|
+
})));
|
|
204
|
+
}
|
|
205
|
+
if (triggers.length === 0) {
|
|
206
|
+
return of();
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
return race(...triggers).pipe(finalize(() => console.log("CLOSED", floatingRef.uid)), exhaustMap(event => floatingRef.close().pipe(map(() => event), distinctUntilChanged())));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function closeTrigger(options = { clickOutside: true, keystroke: true }) {
|
|
214
|
+
return new CloseTriggerTrait(options);
|
|
215
|
+
}
|
|
216
|
+
function getFloatingUid(el, attr, dataset) {
|
|
217
|
+
if (el == null) {
|
|
218
|
+
return undefined;
|
|
219
|
+
}
|
|
220
|
+
if (el.matches(`[${attr}]`)) {
|
|
221
|
+
return Number(el.dataset[dataset]) || undefined;
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
const parent = el.closest(`[${attr}]`);
|
|
225
|
+
if (parent) {
|
|
226
|
+
return Number(parent.dataset[dataset]) || undefined;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return undefined;
|
|
230
|
+
}
|
|
231
|
+
|
|
128
232
|
const DIM_MAP = {
|
|
129
233
|
maxWidth: { computedRef: "max", dimension: "width" },
|
|
130
234
|
maxHeight: { computedRef: "max", dimension: "height" },
|
|
@@ -147,7 +251,7 @@ class DimensionConstraintTrait {
|
|
|
147
251
|
refDim: refDim,
|
|
148
252
|
position: floatingRef.watchTrait("position")
|
|
149
253
|
}).subscribe(({ refDim, position }) => {
|
|
150
|
-
const floating = position.computed?.
|
|
254
|
+
const floating = position.computed?.content;
|
|
151
255
|
if (!floating) {
|
|
152
256
|
return;
|
|
153
257
|
}
|
|
@@ -156,7 +260,7 @@ class DimensionConstraintTrait {
|
|
|
156
260
|
}
|
|
157
261
|
else {
|
|
158
262
|
return floatingRef.watchTrait("position").subscribe(position => {
|
|
159
|
-
const floating = position.computed?.
|
|
263
|
+
const floating = position.computed?.content;
|
|
160
264
|
if (!floating) {
|
|
161
265
|
return;
|
|
162
266
|
}
|
|
@@ -164,7 +268,7 @@ class DimensionConstraintTrait {
|
|
|
164
268
|
dst.next(floating[this.#map.computedRef][this.#map.dimension]);
|
|
165
269
|
}
|
|
166
270
|
else {
|
|
167
|
-
dst.next(clamp(this.value, floating
|
|
271
|
+
dst.next(clamp(this.value, floating.min[this.#map.dimension] || 0, floating.max[this.#map.dimension] || Infinity));
|
|
168
272
|
}
|
|
169
273
|
});
|
|
170
274
|
}
|
|
@@ -231,39 +335,42 @@ function focus(options) {
|
|
|
231
335
|
return new FocusTrait(options);
|
|
232
336
|
}
|
|
233
337
|
|
|
234
|
-
class KeystrokeTrait {
|
|
235
|
-
constructor() {
|
|
236
|
-
this.name = "keystroke";
|
|
237
|
-
}
|
|
238
|
-
connect(floatingRef) {
|
|
239
|
-
const ks = floatingRef.container.injector.get(KeystrokeService);
|
|
240
|
-
return ks
|
|
241
|
-
.watch(floatingRef.container.nativeElement, { key: "Escape", state: "up" })
|
|
242
|
-
.pipe(exhaustMap(() => floatingRef.close()));
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
function keystroke() {
|
|
246
|
-
return new KeystrokeTrait();
|
|
247
|
-
}
|
|
248
|
-
|
|
249
338
|
function computePosition({ floating, anchor, placement, options }) {
|
|
250
339
|
if (options.anchor.margin) {
|
|
251
340
|
anchor = rectExpand(anchor, options.anchor.margin);
|
|
252
341
|
}
|
|
253
342
|
const anchorPoint = rectOrigin(anchor, options.anchor.align);
|
|
254
|
-
let
|
|
343
|
+
let contentRect = rectMoveOrigin(floating, options.content.align, anchorPoint);
|
|
255
344
|
if (options.content.margin) {
|
|
256
|
-
|
|
345
|
+
contentRect = rectContract(contentRect, options.content.margin);
|
|
257
346
|
}
|
|
258
347
|
if (options.placement.padding) {
|
|
259
348
|
placement = rectContract(placement, options.placement.padding);
|
|
260
349
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
350
|
+
return {
|
|
351
|
+
content: {
|
|
352
|
+
...addTLRB(contentRect, placement),
|
|
353
|
+
align: alignmentNormalize(options.content.align),
|
|
354
|
+
connect: anchorPoint,
|
|
355
|
+
max: { width: placement.width - contentRect.x, height: placement.height - contentRect.y },
|
|
356
|
+
min: { width: 0, height: 0 }
|
|
357
|
+
},
|
|
358
|
+
anchor: {
|
|
359
|
+
...addTLRB(anchor, placement),
|
|
360
|
+
align: alignmentNormalize(options.anchor.align),
|
|
361
|
+
connect: anchorPoint
|
|
362
|
+
},
|
|
363
|
+
placement: addTLRB(placement, placement)
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
function addTLRB(rect, container) {
|
|
367
|
+
return {
|
|
368
|
+
...rect,
|
|
369
|
+
top: rect.y,
|
|
370
|
+
left: rect.x,
|
|
371
|
+
right: container.width - (rect.x + rect.width),
|
|
372
|
+
bottom: container.height - (rect.y + rect.height)
|
|
265
373
|
};
|
|
266
|
-
return { floating: cf };
|
|
267
374
|
}
|
|
268
375
|
|
|
269
376
|
class FloatingAnchorRef extends ElementRef {
|
|
@@ -331,12 +438,25 @@ class FloatingPosition {
|
|
|
331
438
|
return;
|
|
332
439
|
}
|
|
333
440
|
const floatingEl = floatingRef.container.nativeElement;
|
|
334
|
-
|
|
335
|
-
|
|
441
|
+
const computedContent = this.computed.content;
|
|
442
|
+
const style = { top: null, right: null, bottom: null, left: null };
|
|
443
|
+
if (computedContent.align.horizontal === "right") {
|
|
444
|
+
style["right"] = `${computedContent.right}px`;
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
style["left"] = `${computedContent.left}px`;
|
|
448
|
+
}
|
|
449
|
+
if (computedContent.align.vertical === "bottom") {
|
|
450
|
+
style["bottom"] = `${computedContent.bottom}px`;
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
style["top"] = `${computedContent.top}px`;
|
|
454
|
+
}
|
|
455
|
+
Object.assign(floatingEl.style, style);
|
|
336
456
|
}
|
|
337
457
|
}
|
|
338
458
|
|
|
339
|
-
function modal(
|
|
459
|
+
function modal() {
|
|
340
460
|
return [
|
|
341
461
|
position({
|
|
342
462
|
anchor: {
|
|
@@ -348,9 +468,9 @@ function modal(options = {}) {
|
|
|
348
468
|
padding: "16px"
|
|
349
469
|
}
|
|
350
470
|
}),
|
|
351
|
-
backdrop({ type: "solid", color: "rgba(0, 0, 0, .3)"
|
|
471
|
+
backdrop({ type: "solid", color: "rgba(0, 0, 0, .3)" }),
|
|
352
472
|
focus({ trap: true }),
|
|
353
|
-
|
|
473
|
+
closeTrigger(),
|
|
354
474
|
fallAnimation()
|
|
355
475
|
];
|
|
356
476
|
}
|
|
@@ -487,12 +607,6 @@ function createElement(options) {
|
|
|
487
607
|
}
|
|
488
608
|
|
|
489
609
|
class BackdropRef extends ChildRef {
|
|
490
|
-
static from(cover, injector, options) {
|
|
491
|
-
const ref = new BackdropRef(document.createElement("div"), cover, injector, options);
|
|
492
|
-
// TODO: kérdéses
|
|
493
|
-
// options.under.state.control(ref.state)
|
|
494
|
-
return ref;
|
|
495
|
-
}
|
|
496
610
|
set visible(visible) {
|
|
497
611
|
if (this.#visible !== visible) {
|
|
498
612
|
this.#visible = visible;
|
|
@@ -502,35 +616,21 @@ class BackdropRef extends ChildRef {
|
|
|
502
616
|
get visible() {
|
|
503
617
|
return this.#visible;
|
|
504
618
|
}
|
|
505
|
-
#visible =
|
|
506
|
-
constructor(
|
|
507
|
-
super(nativeElement);
|
|
508
|
-
this.
|
|
509
|
-
this.
|
|
619
|
+
#visible = false;
|
|
620
|
+
constructor(coverRef, under, options) {
|
|
621
|
+
super(coverRef.nativeElement);
|
|
622
|
+
this.coverRef = coverRef;
|
|
623
|
+
this.under = under;
|
|
510
624
|
this.options = options;
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
}
|
|
520
|
-
this.under = options.under;
|
|
521
|
-
if (options.type === "solid") {
|
|
522
|
-
this.coverSvc
|
|
523
|
-
.solid({ container: nativeElement, color: options.color })
|
|
524
|
-
.pipe(takeUntil(this.disposed$))
|
|
525
|
-
.subscribe();
|
|
526
|
-
this.group = `${options.color === "transparent" ? "transparent" : "solid"}`;
|
|
527
|
-
}
|
|
528
|
-
else if (options.type === "crop") {
|
|
529
|
-
this.coverSvc
|
|
530
|
-
.crop({ container: nativeElement, color: options.color, crop: options.crop })
|
|
531
|
-
.pipe(takeUntil(this.disposed$))
|
|
532
|
-
.subscribe();
|
|
533
|
-
}
|
|
625
|
+
this.group = `${options.color === "transparent" ? "transparent" : "solid"}`;
|
|
626
|
+
this.state.on("showing", () => {
|
|
627
|
+
this.coverRef
|
|
628
|
+
.show()
|
|
629
|
+
.pipe(takeUntil(this.state.onDone("disposed")))
|
|
630
|
+
.subscribe(() => {
|
|
631
|
+
this.visible = true;
|
|
632
|
+
});
|
|
633
|
+
});
|
|
534
634
|
}
|
|
535
635
|
show() {
|
|
536
636
|
return this.state.run("showing", "shown");
|
|
@@ -627,8 +727,9 @@ class LayerService {
|
|
|
627
727
|
}
|
|
628
728
|
return this.append(new ContainerRef(options));
|
|
629
729
|
}
|
|
630
|
-
newBackdrop(options) {
|
|
631
|
-
|
|
730
|
+
newBackdrop(under, options) {
|
|
731
|
+
const coverRef = this.#cover.create(this.root, options);
|
|
732
|
+
return this.append(new BackdropRef(coverRef, under, options));
|
|
632
733
|
}
|
|
633
734
|
append(ref) {
|
|
634
735
|
if (!this.#children.includes(ref)) {
|
|
@@ -656,7 +757,7 @@ class LayerService {
|
|
|
656
757
|
children.sort(sortByZIndexDesc);
|
|
657
758
|
let hasBackdrop = false;
|
|
658
759
|
for (const child of children) {
|
|
659
|
-
if (child instanceof BackdropRef && child.options.
|
|
760
|
+
if (child instanceof BackdropRef && child.options.color !== "transparent") {
|
|
660
761
|
child.visible = !hasBackdrop;
|
|
661
762
|
hasBackdrop = true;
|
|
662
763
|
}
|
|
@@ -730,6 +831,7 @@ function getAlwaysOnTop(child) {
|
|
|
730
831
|
}
|
|
731
832
|
|
|
732
833
|
const TRAITS = new InjectionToken("TRAITS");
|
|
834
|
+
let UID_COUNTER = 0;
|
|
733
835
|
class FloatingRef {
|
|
734
836
|
#traits;
|
|
735
837
|
#untilCleanup;
|
|
@@ -750,8 +852,13 @@ class FloatingRef {
|
|
|
750
852
|
this.#traits = {};
|
|
751
853
|
this.#untilCleanup = this.state.onExecute("cleanup");
|
|
752
854
|
this.#untilDisposed = this.state.onExecute("disposed");
|
|
753
|
-
|
|
754
|
-
container.nativeElement.style
|
|
855
|
+
this.uid = `${++UID_COUNTER}`;
|
|
856
|
+
Object.assign(container.nativeElement.style, {
|
|
857
|
+
overflow: "hidden",
|
|
858
|
+
visibility: "hidden",
|
|
859
|
+
pointerEvents: "none"
|
|
860
|
+
});
|
|
861
|
+
container.nativeElement.setAttribute("data-floating", this.uid);
|
|
755
862
|
this.#traits = traits;
|
|
756
863
|
this.traitState$ = this.#traitState().pipe(shareReplay(1));
|
|
757
864
|
this.state.current$.pipe(takeWhile(state => state !== "cleanup", true)).subscribe(state => {
|
|
@@ -761,6 +868,9 @@ class FloatingRef {
|
|
|
761
868
|
this.state.on("showing", () => {
|
|
762
869
|
container.nativeElement.style.visibility = "visible";
|
|
763
870
|
});
|
|
871
|
+
this.state.on("shown", () => {
|
|
872
|
+
container.nativeElement.style.pointerEvents = null;
|
|
873
|
+
});
|
|
764
874
|
this.state.on("disposing", () => {
|
|
765
875
|
container.nativeElement.style.pointerEvents = "none";
|
|
766
876
|
});
|
|
@@ -795,23 +905,18 @@ class FloatingRef {
|
|
|
795
905
|
this.close(true).subscribe();
|
|
796
906
|
}
|
|
797
907
|
watchTrait(name) {
|
|
798
|
-
return this.traitState$.pipe(takeUntil(this.#untilDisposed),
|
|
908
|
+
return this.traitState$.pipe(takeUntil(this.#untilDisposed), map(state => state[name]), filter(value => value != null));
|
|
799
909
|
}
|
|
800
910
|
#traitState() {
|
|
801
|
-
const src =
|
|
911
|
+
const src = {};
|
|
802
912
|
for (const [k, v] of Object.entries(this.#traits)) {
|
|
803
|
-
src
|
|
804
|
-
return { name: k, data: result };
|
|
805
|
-
})));
|
|
913
|
+
src[k] = v.connect(this).pipe(takeUntil(this.#untilDisposed), startWith(null));
|
|
806
914
|
}
|
|
807
|
-
if (src.length === 0) {
|
|
915
|
+
if (Object.keys(src).length === 0) {
|
|
808
916
|
return EMPTY;
|
|
809
917
|
}
|
|
810
|
-
else if (src.length === 1) {
|
|
811
|
-
return src[0];
|
|
812
|
-
}
|
|
813
918
|
else {
|
|
814
|
-
return
|
|
919
|
+
return combineLatest(src).pipe(shareReplay(1));
|
|
815
920
|
}
|
|
816
921
|
}
|
|
817
922
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.6", ngImport: i0, type: FloatingRef, deps: [{ token: LayerService }, { token: ContainerRef }, { token: TRAITS }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
@@ -969,5 +1074,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.6", ngImpor
|
|
|
969
1074
|
* Generated bundle index. Do not edit.
|
|
970
1075
|
*/
|
|
971
1076
|
|
|
972
|
-
export { AlwaysOnTop, AnimationTrait, AttributeTrait, BackdropRef,
|
|
1077
|
+
export { AlwaysOnTop, AnimationTrait, AttributeTrait, BackdropRef, BackdropTrait, ChildRef, ComponentPortalRef, ContainerRef, DimensionConstraintTrait, DropAnimation, FadeAnimation, FallAnimation, FloatingAnchorRef, FloatingComponentFactory, FloatingFactory, FloatingPlacementRef, FloatingPosition, FloatingRef, FloatingService, FloatingTemplateFactory, FocusTrait, IndividualLayer, LAYER_ZINDEX_START, LayerService, NuFloating, PortalRef, PositionTrait, RootLayer, StyleTrait, TRAITS, TemplatePortalRef, attribute, backdrop, closeTrigger, computePosition, dropAnimation, fadeAnimation, fallAnimation, focus, maxHeight, maxWidth, minHeight, minWidth, modal, position, style };
|
|
973
1078
|
//# sourceMappingURL=ngutil-floating.mjs.map
|