mn-angular-lib 1.0.159 → 1.0.160
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.
|
@@ -3870,10 +3870,17 @@ const mnMultiSelectVariants = tv({
|
|
|
3870
3870
|
* dismissal is reported through {@link dismiss} for the host to act on (run a close
|
|
3871
3871
|
* guard, tear down its overlay, …) rather than being handled here.
|
|
3872
3872
|
*
|
|
3873
|
-
* Positioning is `position: fixed` against the viewport, so
|
|
3874
|
-
*
|
|
3875
|
-
*
|
|
3876
|
-
*
|
|
3873
|
+
* Positioning is `position: fixed` against the viewport, so the host relocates itself
|
|
3874
|
+
* to `document.body` on init and blocks scrolling behind it while open. Both are
|
|
3875
|
+
* unconditional: rendering viewport-fixed chrome in place made correctness depend on
|
|
3876
|
+
* where a consumer happened to write the tag. A `transform`/`filter`/`contain`
|
|
3877
|
+
* ancestor becomes the containing block and pushes the sheet to the middle of the
|
|
3878
|
+
* screen — which a *stacked* modal did to its own sheet — and, because `position:
|
|
3879
|
+
* fixed` moves where an element paints but not where it sits in the DOM, a gesture on
|
|
3880
|
+
* the backdrop still scrolled whichever ancestor was the scroll container.
|
|
3881
|
+
*
|
|
3882
|
+
* The multi-select and dropdown used to do the relocating themselves; that is why the
|
|
3883
|
+
* behaviour reads as new here but is not new to them.
|
|
3877
3884
|
*/
|
|
3878
3885
|
class MnBottomSheet {
|
|
3879
3886
|
/** Tailwind's `sm` breakpoint — at or below this the swipe gesture is armed.
|
|
@@ -3945,6 +3952,71 @@ class MnBottomSheet {
|
|
|
3945
3952
|
/** In-flight exit animation, so a swipe-dismiss and a follow-up programmatic
|
|
3946
3953
|
* {@link startClosing} share one glide instead of re-triggering it. */
|
|
3947
3954
|
exitPromise = null;
|
|
3955
|
+
/** The host node once moved to `document.body`, so it is only detached if we moved it. */
|
|
3956
|
+
portalledHost = null;
|
|
3957
|
+
/** Blocks scroll gestures aimed at anything behind the sheet, while it is open. */
|
|
3958
|
+
scrollGuard = null;
|
|
3959
|
+
/** Moves the host out to `document.body` and stops the page behind scrolling. */
|
|
3960
|
+
ngOnInit() {
|
|
3961
|
+
if (typeof document === 'undefined')
|
|
3962
|
+
return;
|
|
3963
|
+
const host = this.el.nativeElement;
|
|
3964
|
+
document.body.appendChild(host);
|
|
3965
|
+
this.portalledHost = host;
|
|
3966
|
+
this.lockScroll();
|
|
3967
|
+
}
|
|
3968
|
+
/**
|
|
3969
|
+
* Stops pointer scrolling behind the sheet for as long as it is open.
|
|
3970
|
+
*
|
|
3971
|
+
* Cancels the gesture rather than setting `overflow: hidden` on `document.body`: an
|
|
3972
|
+
* app whose scroll container is a layout element (a `<main>`, a drawer body) leaves
|
|
3973
|
+
* `body` unscrollable, so locking it there is a no-op and the page still slides about
|
|
3974
|
+
* under the sheet. Cancelling `wheel` and `touchmove` before anything acts on them
|
|
3975
|
+
* holds regardless of which element does the scrolling.
|
|
3976
|
+
*
|
|
3977
|
+
* Gestures that begin inside the sheet are let through so its own content still
|
|
3978
|
+
* scrolls; `overscroll-behavior: contain` keeps those from chaining out at the ends.
|
|
3979
|
+
*
|
|
3980
|
+
* Pointer input only. Page Down and the arrows still reach the page behind when focus
|
|
3981
|
+
* is left there — closing that needs either a key filter or moving focus into the
|
|
3982
|
+
* sheet, and neither belongs in this change.
|
|
3983
|
+
*/
|
|
3984
|
+
lockScroll() {
|
|
3985
|
+
const guard = (event) => {
|
|
3986
|
+
const target = event.target;
|
|
3987
|
+
const container = this.containerRef()?.nativeElement;
|
|
3988
|
+
if (container && target && container.contains(target))
|
|
3989
|
+
return;
|
|
3990
|
+
// Only cancellable events can be stopped; a passive listener elsewhere in the
|
|
3991
|
+
// chain would otherwise log a console error for a no-op preventDefault.
|
|
3992
|
+
if (event.cancelable)
|
|
3993
|
+
event.preventDefault();
|
|
3994
|
+
};
|
|
3995
|
+
// Capture phase, so the gesture is cancelled before any scroller sees it.
|
|
3996
|
+
document.addEventListener('wheel', guard, { capture: true, passive: false });
|
|
3997
|
+
document.addEventListener('touchmove', guard, { capture: true, passive: false });
|
|
3998
|
+
this.scrollGuard = guard;
|
|
3999
|
+
}
|
|
4000
|
+
/** Releases the scroll guard. Idempotent. */
|
|
4001
|
+
unlockScroll() {
|
|
4002
|
+
if (!this.scrollGuard)
|
|
4003
|
+
return;
|
|
4004
|
+
document.removeEventListener('wheel', this.scrollGuard, { capture: true });
|
|
4005
|
+
document.removeEventListener('touchmove', this.scrollGuard, { capture: true });
|
|
4006
|
+
this.scrollGuard = null;
|
|
4007
|
+
}
|
|
4008
|
+
/**
|
|
4009
|
+
* Detaches the relocated host.
|
|
4010
|
+
*
|
|
4011
|
+
* Angular tears a view down by removing the nodes it created from their parent; a
|
|
4012
|
+
* host we moved to `body` is no longer among the parent's children, so without
|
|
4013
|
+
* this the sheet would outlive the view that declared it.
|
|
4014
|
+
*/
|
|
4015
|
+
ngOnDestroy() {
|
|
4016
|
+
this.unlockScroll();
|
|
4017
|
+
this.portalledHost?.remove();
|
|
4018
|
+
this.portalledHost = null;
|
|
4019
|
+
}
|
|
3948
4020
|
get hostClasses() {
|
|
3949
4021
|
return `mn-bottom-sheet${this.isDismissing ? ' is-dismissing' : ''}`
|
|
3950
4022
|
+ `${this.growWithKeyboard ? ' grow-with-keyboard' : ''}`;
|
|
@@ -4093,11 +4165,11 @@ class MnBottomSheet {
|
|
|
4093
4165
|
&& window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
4094
4166
|
}
|
|
4095
4167
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MnBottomSheet, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4096
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: MnBottomSheet, isStandalone: true, selector: "mn-bottom-sheet", inputs: { showBackdrop: "showBackdrop", showGrabber: "showGrabber", dismissible: "dismissible", minHeightPx: "minHeightPx", maxHeightVh: "maxHeightVh", containerClass: "containerClass", ariaLabel: "ariaLabel", ariaLabelledby: "ariaLabelledby", growWithKeyboard: "growWithKeyboard", dismissGuard: "dismissGuard" }, outputs: { dismiss: "dismiss" }, host: { properties: { "class": "this.hostClasses" } }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (showBackdrop) {\n <!-- Dims the page behind the sheet. Tapping it dismisses when the sheet is dismissible. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events,@angular-eslint/template/interactive-supports-focus -->\n <div (click)=\"onBackdropClick()\" class=\"mn-sheet-backdrop fixed inset-0 z-9998 bg-black/40\"></div>\n}\n\n<div\n #container\n [attr.aria-label]=\"ariaLabelledby ? null : (ariaLabel || null)\"\n [attr.aria-labelledby]=\"ariaLabelledby || null\"\n [class.sheet-dragging]=\"isDraggingSheet\"\n [ngClass]=\"containerClass\"\n [style.--mn-sheet-max]=\"maxHeightVh + 'vh'\"\n [style.max-height.vh]=\"maxHeightVh\"\n [style.min-height.px]=\"minHeightPx\"\n [style.transform]=\"sheetDragY ? 'translateY(' + sheetDragY + 'px)' : null\"\n aria-modal=\"true\"\n class=\"mn-sheet-container fixed inset-x-0 bottom-0 z-9999 flex flex-col bg-base-100 border-t border-base-300 rounded-t-2xl shadow-lg\"\n role=\"dialog\"\n tabindex=\"-1\"\n>\n @if (showGrabber) {\n <!-- Drag handle for swipe-to-dismiss. The gesture is armed on the whole handle;\n drags starting on a control inside the projected content are ignored. -->\n <div\n (pointercancel)=\"onSheetPointerUp()\"\n (pointerdown)=\"onSheetPointerDown($event)\"\n (pointermove)=\"onSheetPointerMove($event)\"\n (pointerup)=\"onSheetPointerUp()\"\n class=\"flex justify-center pt-2 pb-1 touch-none cursor-grab shrink-0\"\n >\n <div class=\"h-1.5 w-10 rounded-full bg-base-300\"></div>\n </div>\n }\n\n <ng-content></ng-content>\n</div>\n", styles: [":host{--mn-sheet-ease: cubic-bezier(.32, .72, 0, 1);display:contents}.mn-sheet-container{padding-bottom:env(safe-area-inset-bottom);min-height:0;transition:transform .35s var(--mn-sheet-ease),min-height .25s var(--mn-sheet-ease);animation:mn-sheet-in .35s var(--mn-sheet-ease)}:host(.grow-with-keyboard):host-context(.mn-keyboard-open) .mn-sheet-container{min-height:var(--mn-sheet-max, 92vh)}.mn-sheet-container.sheet-dragging{transition:none}.mn-sheet-backdrop{animation:mn-sheet-backdrop-in .2s ease-out}:host(.is-dismissing) .mn-sheet-container{animation:none}@keyframes mn-sheet-in{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes mn-sheet-backdrop-in{0%{opacity:0}to{opacity:1}}@media(prefers-reduced-motion:reduce){.mn-sheet-container,.mn-sheet-backdrop{animation-duration:.01ms!important;transition-duration:.01ms!important}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
4168
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: MnBottomSheet, isStandalone: true, selector: "mn-bottom-sheet", inputs: { showBackdrop: "showBackdrop", showGrabber: "showGrabber", dismissible: "dismissible", minHeightPx: "minHeightPx", maxHeightVh: "maxHeightVh", containerClass: "containerClass", ariaLabel: "ariaLabel", ariaLabelledby: "ariaLabelledby", growWithKeyboard: "growWithKeyboard", dismissGuard: "dismissGuard" }, outputs: { dismiss: "dismiss" }, host: { properties: { "class": "this.hostClasses" } }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (showBackdrop) {\n <!-- Dims the page behind the sheet. Tapping it dismisses when the sheet is dismissible. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events,@angular-eslint/template/interactive-supports-focus -->\n <div (click)=\"onBackdropClick()\" class=\"mn-sheet-backdrop fixed inset-0 z-9998 bg-black/40\"></div>\n}\n\n<div\n #container\n [attr.aria-label]=\"ariaLabelledby ? null : (ariaLabel || null)\"\n [attr.aria-labelledby]=\"ariaLabelledby || null\"\n [class.sheet-dragging]=\"isDraggingSheet\"\n [ngClass]=\"containerClass\"\n [style.--mn-sheet-max]=\"maxHeightVh + 'vh'\"\n [style.max-height.vh]=\"maxHeightVh\"\n [style.min-height.px]=\"minHeightPx\"\n [style.transform]=\"sheetDragY ? 'translateY(' + sheetDragY + 'px)' : null\"\n aria-modal=\"true\"\n class=\"mn-sheet-container fixed inset-x-0 bottom-0 z-9999 flex flex-col bg-base-100 border-t border-base-300 rounded-t-2xl shadow-lg\"\n role=\"dialog\"\n tabindex=\"-1\"\n>\n @if (showGrabber) {\n <!-- Drag handle for swipe-to-dismiss. The gesture is armed on the whole handle;\n drags starting on a control inside the projected content are ignored. -->\n <div\n (pointercancel)=\"onSheetPointerUp()\"\n (pointerdown)=\"onSheetPointerDown($event)\"\n (pointermove)=\"onSheetPointerMove($event)\"\n (pointerup)=\"onSheetPointerUp()\"\n class=\"flex justify-center pt-2 pb-1 touch-none cursor-grab shrink-0\"\n >\n <div class=\"h-1.5 w-10 rounded-full bg-base-300\"></div>\n </div>\n }\n\n <ng-content></ng-content>\n</div>\n", styles: [":host{--mn-sheet-ease: cubic-bezier(.32, .72, 0, 1);display:contents}.mn-sheet-container{padding-bottom:env(safe-area-inset-bottom);overscroll-behavior:contain;min-height:0;transition:transform .35s var(--mn-sheet-ease),min-height .25s var(--mn-sheet-ease);animation:mn-sheet-in .35s var(--mn-sheet-ease)}:host(.grow-with-keyboard):host-context(.mn-keyboard-open) .mn-sheet-container{min-height:var(--mn-sheet-max, 92vh)}.mn-sheet-container.sheet-dragging{transition:none}.mn-sheet-backdrop{animation:mn-sheet-backdrop-in .2s ease-out}:host(.is-dismissing) .mn-sheet-container{animation:none}@keyframes mn-sheet-in{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes mn-sheet-backdrop-in{0%{opacity:0}to{opacity:1}}@media(prefers-reduced-motion:reduce){.mn-sheet-container,.mn-sheet-backdrop{animation-duration:.01ms!important;transition-duration:.01ms!important}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
4097
4169
|
}
|
|
4098
4170
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MnBottomSheet, decorators: [{
|
|
4099
4171
|
type: Component,
|
|
4100
|
-
args: [{ selector: 'mn-bottom-sheet', standalone: true, imports: [NgClass], template: "@if (showBackdrop) {\n <!-- Dims the page behind the sheet. Tapping it dismisses when the sheet is dismissible. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events,@angular-eslint/template/interactive-supports-focus -->\n <div (click)=\"onBackdropClick()\" class=\"mn-sheet-backdrop fixed inset-0 z-9998 bg-black/40\"></div>\n}\n\n<div\n #container\n [attr.aria-label]=\"ariaLabelledby ? null : (ariaLabel || null)\"\n [attr.aria-labelledby]=\"ariaLabelledby || null\"\n [class.sheet-dragging]=\"isDraggingSheet\"\n [ngClass]=\"containerClass\"\n [style.--mn-sheet-max]=\"maxHeightVh + 'vh'\"\n [style.max-height.vh]=\"maxHeightVh\"\n [style.min-height.px]=\"minHeightPx\"\n [style.transform]=\"sheetDragY ? 'translateY(' + sheetDragY + 'px)' : null\"\n aria-modal=\"true\"\n class=\"mn-sheet-container fixed inset-x-0 bottom-0 z-9999 flex flex-col bg-base-100 border-t border-base-300 rounded-t-2xl shadow-lg\"\n role=\"dialog\"\n tabindex=\"-1\"\n>\n @if (showGrabber) {\n <!-- Drag handle for swipe-to-dismiss. The gesture is armed on the whole handle;\n drags starting on a control inside the projected content are ignored. -->\n <div\n (pointercancel)=\"onSheetPointerUp()\"\n (pointerdown)=\"onSheetPointerDown($event)\"\n (pointermove)=\"onSheetPointerMove($event)\"\n (pointerup)=\"onSheetPointerUp()\"\n class=\"flex justify-center pt-2 pb-1 touch-none cursor-grab shrink-0\"\n >\n <div class=\"h-1.5 w-10 rounded-full bg-base-300\"></div>\n </div>\n }\n\n <ng-content></ng-content>\n</div>\n", styles: [":host{--mn-sheet-ease: cubic-bezier(.32, .72, 0, 1);display:contents}.mn-sheet-container{padding-bottom:env(safe-area-inset-bottom);min-height:0;transition:transform .35s var(--mn-sheet-ease),min-height .25s var(--mn-sheet-ease);animation:mn-sheet-in .35s var(--mn-sheet-ease)}:host(.grow-with-keyboard):host-context(.mn-keyboard-open) .mn-sheet-container{min-height:var(--mn-sheet-max, 92vh)}.mn-sheet-container.sheet-dragging{transition:none}.mn-sheet-backdrop{animation:mn-sheet-backdrop-in .2s ease-out}:host(.is-dismissing) .mn-sheet-container{animation:none}@keyframes mn-sheet-in{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes mn-sheet-backdrop-in{0%{opacity:0}to{opacity:1}}@media(prefers-reduced-motion:reduce){.mn-sheet-container,.mn-sheet-backdrop{animation-duration:.01ms!important;transition-duration:.01ms!important}}\n"] }]
|
|
4172
|
+
args: [{ selector: 'mn-bottom-sheet', standalone: true, imports: [NgClass], template: "@if (showBackdrop) {\n <!-- Dims the page behind the sheet. Tapping it dismisses when the sheet is dismissible. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events,@angular-eslint/template/interactive-supports-focus -->\n <div (click)=\"onBackdropClick()\" class=\"mn-sheet-backdrop fixed inset-0 z-9998 bg-black/40\"></div>\n}\n\n<div\n #container\n [attr.aria-label]=\"ariaLabelledby ? null : (ariaLabel || null)\"\n [attr.aria-labelledby]=\"ariaLabelledby || null\"\n [class.sheet-dragging]=\"isDraggingSheet\"\n [ngClass]=\"containerClass\"\n [style.--mn-sheet-max]=\"maxHeightVh + 'vh'\"\n [style.max-height.vh]=\"maxHeightVh\"\n [style.min-height.px]=\"minHeightPx\"\n [style.transform]=\"sheetDragY ? 'translateY(' + sheetDragY + 'px)' : null\"\n aria-modal=\"true\"\n class=\"mn-sheet-container fixed inset-x-0 bottom-0 z-9999 flex flex-col bg-base-100 border-t border-base-300 rounded-t-2xl shadow-lg\"\n role=\"dialog\"\n tabindex=\"-1\"\n>\n @if (showGrabber) {\n <!-- Drag handle for swipe-to-dismiss. The gesture is armed on the whole handle;\n drags starting on a control inside the projected content are ignored. -->\n <div\n (pointercancel)=\"onSheetPointerUp()\"\n (pointerdown)=\"onSheetPointerDown($event)\"\n (pointermove)=\"onSheetPointerMove($event)\"\n (pointerup)=\"onSheetPointerUp()\"\n class=\"flex justify-center pt-2 pb-1 touch-none cursor-grab shrink-0\"\n >\n <div class=\"h-1.5 w-10 rounded-full bg-base-300\"></div>\n </div>\n }\n\n <ng-content></ng-content>\n</div>\n", styles: [":host{--mn-sheet-ease: cubic-bezier(.32, .72, 0, 1);display:contents}.mn-sheet-container{padding-bottom:env(safe-area-inset-bottom);overscroll-behavior:contain;min-height:0;transition:transform .35s var(--mn-sheet-ease),min-height .25s var(--mn-sheet-ease);animation:mn-sheet-in .35s var(--mn-sheet-ease)}:host(.grow-with-keyboard):host-context(.mn-keyboard-open) .mn-sheet-container{min-height:var(--mn-sheet-max, 92vh)}.mn-sheet-container.sheet-dragging{transition:none}.mn-sheet-backdrop{animation:mn-sheet-backdrop-in .2s ease-out}:host(.is-dismissing) .mn-sheet-container{animation:none}@keyframes mn-sheet-in{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes mn-sheet-backdrop-in{0%{opacity:0}to{opacity:1}}@media(prefers-reduced-motion:reduce){.mn-sheet-container,.mn-sheet-backdrop{animation-duration:.01ms!important;transition-duration:.01ms!important}}\n"] }]
|
|
4101
4173
|
}], propDecorators: { showBackdrop: [{
|
|
4102
4174
|
type: Input
|
|
4103
4175
|
}], showGrabber: [{
|
|
@@ -4183,8 +4255,8 @@ class MnMultiSelect {
|
|
|
4183
4255
|
* card) used to leave the portalled panel floating at its stale coordinates.
|
|
4184
4256
|
*/
|
|
4185
4257
|
scrollCapture = null;
|
|
4186
|
-
/** The bottom-sheet host
|
|
4187
|
-
|
|
4258
|
+
/** The bottom-sheet host, for outside-click tests. The sheet owns its own placement. */
|
|
4259
|
+
sheetHost = null;
|
|
4188
4260
|
/**
|
|
4189
4261
|
* The dropdown panel element, queried while it is rendered by the `@if` block.
|
|
4190
4262
|
* The setter relocates the panel to `document.body` so that its `position: fixed`
|
|
@@ -4221,14 +4293,13 @@ class MnMultiSelect {
|
|
|
4221
4293
|
this.ngControl.valueAccessor = this;
|
|
4222
4294
|
}
|
|
4223
4295
|
/**
|
|
4224
|
-
* The bottom-sheet host,
|
|
4225
|
-
* `document.body
|
|
4226
|
-
*
|
|
4227
|
-
* its container height is captured as the sheet's `min-height` floor.
|
|
4296
|
+
* The bottom-sheet host, kept as a reference for outside-click tests. The sheet
|
|
4297
|
+
* relocates itself to `document.body`, so nothing is moved here. On open its
|
|
4298
|
+
* container height is captured as the sheet's `min-height` floor.
|
|
4228
4299
|
*/
|
|
4229
4300
|
set sheetRef(ref) {
|
|
4230
4301
|
const el = ref?.nativeElement ?? null;
|
|
4231
|
-
this.
|
|
4302
|
+
this.sheetHost = el;
|
|
4232
4303
|
if (el) {
|
|
4233
4304
|
this.captureSheetFloor(el);
|
|
4234
4305
|
}
|
|
@@ -4277,7 +4348,7 @@ class MnMultiSelect {
|
|
|
4277
4348
|
// Guarantee the portalled elements never outlive the component.
|
|
4278
4349
|
this.movedPanel = this.portal(null, this.movedPanel);
|
|
4279
4350
|
this.movedShield = this.portal(null, this.movedShield);
|
|
4280
|
-
this.
|
|
4351
|
+
this.sheetHost = null;
|
|
4281
4352
|
});
|
|
4282
4353
|
}
|
|
4283
4354
|
resolveConfig() {
|
|
@@ -4356,7 +4427,7 @@ class MnMultiSelect {
|
|
|
4356
4427
|
const insidePanel = !!target && !!this.movedPanel && this.movedPanel.contains(target);
|
|
4357
4428
|
// In sheet mode the backdrop tap is handled by mn-bottom-sheet's own (dismiss); the
|
|
4358
4429
|
// sheet host counts as "inside" here so this listener never double-fires the close.
|
|
4359
|
-
const insideSheet = !!target && !!this.
|
|
4430
|
+
const insideSheet = !!target && !!this.sheetHost && this.sheetHost.contains(target);
|
|
4360
4431
|
if (!insideHost && !insidePanel && !insideSheet) {
|
|
4361
4432
|
this.close();
|
|
4362
4433
|
}
|
|
@@ -4382,7 +4453,7 @@ class MnMultiSelect {
|
|
|
4382
4453
|
}
|
|
4383
4454
|
requestAnimationFrame(() => {
|
|
4384
4455
|
// The sheet may have closed before the frame ran; don't strand a stale floor.
|
|
4385
|
-
if (!this.isOpen || this.
|
|
4456
|
+
if (!this.isOpen || this.sheetHost !== hostEl)
|
|
4386
4457
|
return;
|
|
4387
4458
|
this.sheetFloorPx = measure();
|
|
4388
4459
|
this.cdr.markForCheck();
|
|
@@ -4810,8 +4881,8 @@ class MnDropdown {
|
|
|
4810
4881
|
static SHEET_MAX_WIDTH = 639.98;
|
|
4811
4882
|
/** The anchored popover panel currently moved into `document.body`, if any. */
|
|
4812
4883
|
movedPanel = null;
|
|
4813
|
-
/** The bottom-sheet host
|
|
4814
|
-
|
|
4884
|
+
/** The bottom-sheet host, for outside-click tests. The sheet owns its own placement. */
|
|
4885
|
+
sheetHost = null;
|
|
4815
4886
|
/** Whether the viewport is currently narrow enough for the sheet layout. */
|
|
4816
4887
|
isNarrowViewport = false;
|
|
4817
4888
|
/** Live breakpoint match, so rotating the device re-evaluates the layout. */
|
|
@@ -4875,7 +4946,7 @@ class MnDropdown {
|
|
|
4875
4946
|
*/
|
|
4876
4947
|
set sheetRef(ref) {
|
|
4877
4948
|
const el = ref?.nativeElement ?? null;
|
|
4878
|
-
this.
|
|
4949
|
+
this.sheetHost = el;
|
|
4879
4950
|
if (el && this.isSearchable) {
|
|
4880
4951
|
this.captureSheetFloor(el);
|
|
4881
4952
|
}
|
|
@@ -4897,7 +4968,7 @@ class MnDropdown {
|
|
|
4897
4968
|
this.unlockBodyScroll();
|
|
4898
4969
|
// Guarantee the portalled elements never outlive the component.
|
|
4899
4970
|
this.movedPanel = this.portal(null, this.movedPanel);
|
|
4900
|
-
this.
|
|
4971
|
+
this.sheetHost = null;
|
|
4901
4972
|
});
|
|
4902
4973
|
}
|
|
4903
4974
|
resolveConfig() {
|
|
@@ -5054,7 +5125,7 @@ class MnDropdown {
|
|
|
5054
5125
|
const target = event.target;
|
|
5055
5126
|
const insideHost = !!target && this.elRef.nativeElement.contains(target);
|
|
5056
5127
|
const insidePanel = !!target && !!this.movedPanel && this.movedPanel.contains(target);
|
|
5057
|
-
const insideSheet = !!target && !!this.
|
|
5128
|
+
const insideSheet = !!target && !!this.sheetHost && this.sheetHost.contains(target);
|
|
5058
5129
|
if (!insideHost && !insidePanel && !insideSheet) {
|
|
5059
5130
|
this.close();
|
|
5060
5131
|
}
|
|
@@ -5131,7 +5202,7 @@ class MnDropdown {
|
|
|
5131
5202
|
return;
|
|
5132
5203
|
}
|
|
5133
5204
|
requestAnimationFrame(() => {
|
|
5134
|
-
if (!this.isOpen || this.
|
|
5205
|
+
if (!this.isOpen || this.sheetHost !== hostEl)
|
|
5135
5206
|
return;
|
|
5136
5207
|
this.sheetFloorPx = measure();
|
|
5137
5208
|
this.cdr.markForCheck();
|