350 lines
16 KiB
JavaScript
350 lines
16 KiB
JavaScript
import { __esDecorate, __runInitializers } from 'tslib';
|
|
import { Directionality, BidiModule } from '@angular/cdk/bidi';
|
|
import { Platform, PlatformModule } from '@angular/cdk/platform';
|
|
import * as i0 from '@angular/core';
|
|
import { inject, Renderer2, ChangeDetectorRef, DestroyRef, EventEmitter, ElementRef, DOCUMENT, Output, Input, ViewChild, ViewEncapsulation, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
|
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
import { Subscription, ReplaySubject, merge } from 'rxjs';
|
|
import { map, throttleTime } from 'rxjs/operators';
|
|
import { NzResizeObserver } from 'ng-zorro-antd/cdk/resize-observer';
|
|
import { WithConfig, NzConfigService } from 'ng-zorro-antd/core/config';
|
|
import { NzScrollService } from 'ng-zorro-antd/core/services';
|
|
import { fromEventOutsideAngular, shallowEqual, getStyleAsText, numberAttributeWithZeroFallback } from 'ng-zorro-antd/core/util';
|
|
|
|
/**
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
|
|
*/
|
|
var AffixRespondEvents;
|
|
(function (AffixRespondEvents) {
|
|
AffixRespondEvents["resize"] = "resize";
|
|
AffixRespondEvents["scroll"] = "scroll";
|
|
AffixRespondEvents["touchstart"] = "touchstart";
|
|
AffixRespondEvents["touchmove"] = "touchmove";
|
|
AffixRespondEvents["touchend"] = "touchend";
|
|
AffixRespondEvents["pageshow"] = "pageshow";
|
|
AffixRespondEvents["load"] = "LOAD";
|
|
})(AffixRespondEvents || (AffixRespondEvents = {}));
|
|
|
|
/**
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
|
|
*/
|
|
function isTargetWindow(target) {
|
|
return typeof window !== 'undefined' && target === window;
|
|
}
|
|
function getTargetRect(target) {
|
|
return !isTargetWindow(target)
|
|
? target.getBoundingClientRect()
|
|
: {
|
|
top: 0,
|
|
left: 0,
|
|
bottom: 0
|
|
};
|
|
}
|
|
|
|
const NZ_CONFIG_MODULE_NAME = 'affix';
|
|
const NZ_AFFIX_CLS_PREFIX = 'ant-affix';
|
|
const NZ_AFFIX_DEFAULT_SCROLL_TIME = 20;
|
|
let NzAffixComponent = (() => {
|
|
let _nzOffsetTop_decorators;
|
|
let _nzOffsetTop_initializers = [];
|
|
let _nzOffsetTop_extraInitializers = [];
|
|
let _nzOffsetBottom_decorators;
|
|
let _nzOffsetBottom_initializers = [];
|
|
let _nzOffsetBottom_extraInitializers = [];
|
|
return class NzAffixComponent {
|
|
static {
|
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
_nzOffsetTop_decorators = [WithConfig()];
|
|
_nzOffsetBottom_decorators = [WithConfig()];
|
|
__esDecorate(null, null, _nzOffsetTop_decorators, { kind: "field", name: "nzOffsetTop", static: false, private: false, access: { has: obj => "nzOffsetTop" in obj, get: obj => obj.nzOffsetTop, set: (obj, value) => { obj.nzOffsetTop = value; } }, metadata: _metadata }, _nzOffsetTop_initializers, _nzOffsetTop_extraInitializers);
|
|
__esDecorate(null, null, _nzOffsetBottom_decorators, { kind: "field", name: "nzOffsetBottom", static: false, private: false, access: { has: obj => "nzOffsetBottom" in obj, get: obj => obj.nzOffsetBottom, set: (obj, value) => { obj.nzOffsetBottom = value; } }, metadata: _metadata }, _nzOffsetBottom_initializers, _nzOffsetBottom_extraInitializers);
|
|
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
}
|
|
nzConfigService = inject(NzConfigService);
|
|
scrollSrv = inject(NzScrollService);
|
|
platform = inject(Platform);
|
|
renderer = inject(Renderer2);
|
|
nzResizeObserver = inject(NzResizeObserver);
|
|
cdr = inject(ChangeDetectorRef);
|
|
directionality = inject(Directionality);
|
|
destroyRef = inject(DestroyRef);
|
|
_nzModuleName = NZ_CONFIG_MODULE_NAME;
|
|
fixedEl;
|
|
nzTarget;
|
|
nzOffsetTop = __runInitializers(this, _nzOffsetTop_initializers, void 0);
|
|
nzOffsetBottom = (__runInitializers(this, _nzOffsetTop_extraInitializers), __runInitializers(this, _nzOffsetBottom_initializers, void 0));
|
|
nzChange = (__runInitializers(this, _nzOffsetBottom_extraInitializers), new EventEmitter());
|
|
dir = 'ltr';
|
|
placeholderNode = inject((ElementRef)).nativeElement;
|
|
affixStyle;
|
|
placeholderStyle;
|
|
positionChangeSubscription = Subscription.EMPTY;
|
|
offsetChanged$ = new ReplaySubject(1);
|
|
timeout;
|
|
document = inject(DOCUMENT);
|
|
get target() {
|
|
const el = this.nzTarget;
|
|
return (typeof el === 'string' ? this.document.querySelector(el) : el) || window;
|
|
}
|
|
constructor() {
|
|
this.destroyRef.onDestroy(() => {
|
|
this.removeListeners();
|
|
});
|
|
}
|
|
ngOnInit() {
|
|
this.directionality.change?.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((direction) => {
|
|
this.dir = direction;
|
|
this.registerListeners();
|
|
this.updatePosition({});
|
|
this.cdr.detectChanges();
|
|
});
|
|
this.dir = this.directionality.value;
|
|
}
|
|
ngOnChanges(changes) {
|
|
const { nzOffsetBottom, nzOffsetTop, nzTarget } = changes;
|
|
if (nzOffsetBottom || nzOffsetTop) {
|
|
this.offsetChanged$.next();
|
|
}
|
|
if (nzTarget) {
|
|
this.registerListeners();
|
|
}
|
|
}
|
|
ngAfterViewInit() {
|
|
this.registerListeners();
|
|
}
|
|
registerListeners() {
|
|
if (!this.platform.isBrowser) {
|
|
return;
|
|
}
|
|
this.removeListeners();
|
|
const el = this.target === window ? this.document.body : this.target;
|
|
this.positionChangeSubscription = merge(...Object.keys(AffixRespondEvents).map(evName => fromEventOutsideAngular(this.target, evName)), this.offsetChanged$.pipe(map(() => ({}))), this.nzResizeObserver.observe(el))
|
|
.pipe(throttleTime(NZ_AFFIX_DEFAULT_SCROLL_TIME, undefined, { trailing: true }), takeUntilDestroyed(this.destroyRef))
|
|
.subscribe(e => this.updatePosition(e));
|
|
this.timeout = setTimeout(() => this.updatePosition({}));
|
|
}
|
|
removeListeners() {
|
|
clearTimeout(this.timeout);
|
|
this.positionChangeSubscription.unsubscribe();
|
|
}
|
|
getOffset(element, target) {
|
|
const elemRect = element.getBoundingClientRect();
|
|
const targetRect = getTargetRect(target);
|
|
const scrollTop = this.scrollSrv.getScroll(target, true);
|
|
const scrollLeft = this.scrollSrv.getScroll(target, false);
|
|
const docElem = this.document.body;
|
|
const clientTop = docElem.clientTop || 0;
|
|
const clientLeft = docElem.clientLeft || 0;
|
|
return {
|
|
top: elemRect.top - targetRect.top + scrollTop - clientTop,
|
|
left: elemRect.left - targetRect.left + scrollLeft - clientLeft,
|
|
width: elemRect.width,
|
|
height: elemRect.height
|
|
};
|
|
}
|
|
setAffixStyle(e, affixStyle) {
|
|
const originalAffixStyle = this.affixStyle;
|
|
const isWindow = this.target === window;
|
|
if (e.type === 'scroll' && originalAffixStyle && affixStyle && isWindow) {
|
|
return;
|
|
}
|
|
if (shallowEqual(originalAffixStyle, affixStyle)) {
|
|
return;
|
|
}
|
|
const fixed = !!affixStyle;
|
|
const wrapEl = this.fixedEl.nativeElement;
|
|
this.renderer.setStyle(wrapEl, 'cssText', getStyleAsText(affixStyle));
|
|
this.affixStyle = affixStyle;
|
|
if (fixed) {
|
|
wrapEl.classList.add(NZ_AFFIX_CLS_PREFIX);
|
|
}
|
|
else {
|
|
wrapEl.classList.remove(NZ_AFFIX_CLS_PREFIX);
|
|
}
|
|
this.updateRtlClass();
|
|
if ((affixStyle && !originalAffixStyle) || (!affixStyle && originalAffixStyle)) {
|
|
this.nzChange.emit(fixed);
|
|
}
|
|
}
|
|
setPlaceholderStyle(placeholderStyle) {
|
|
const originalPlaceholderStyle = this.placeholderStyle;
|
|
if (shallowEqual(placeholderStyle, originalPlaceholderStyle)) {
|
|
return;
|
|
}
|
|
this.renderer.setStyle(this.placeholderNode, 'cssText', getStyleAsText(placeholderStyle));
|
|
this.placeholderStyle = placeholderStyle;
|
|
}
|
|
syncPlaceholderStyle(e) {
|
|
if (!this.affixStyle) {
|
|
return;
|
|
}
|
|
this.renderer.setStyle(this.placeholderNode, 'cssText', '');
|
|
this.placeholderStyle = undefined;
|
|
const styleObj = {
|
|
width: this.placeholderNode.offsetWidth,
|
|
height: this.fixedEl.nativeElement.offsetHeight
|
|
};
|
|
this.setAffixStyle(e, {
|
|
...this.affixStyle,
|
|
...styleObj
|
|
});
|
|
this.setPlaceholderStyle(styleObj);
|
|
}
|
|
updatePosition(e) {
|
|
if (!this.platform.isBrowser) {
|
|
return;
|
|
}
|
|
const targetNode = this.target;
|
|
let offsetTop = this.nzOffsetTop;
|
|
const scrollTop = this.scrollSrv.getScroll(targetNode, true);
|
|
const elemOffset = this.getOffset(this.placeholderNode, targetNode);
|
|
const fixedNode = this.fixedEl.nativeElement;
|
|
const elemSize = {
|
|
width: fixedNode.offsetWidth,
|
|
height: fixedNode.offsetHeight
|
|
};
|
|
const offsetMode = {
|
|
top: false,
|
|
bottom: false
|
|
};
|
|
// Default to `offsetTop=0`.
|
|
if (typeof offsetTop !== 'number' && typeof this.nzOffsetBottom !== 'number') {
|
|
offsetMode.top = true;
|
|
offsetTop = 0;
|
|
}
|
|
else {
|
|
offsetMode.top = typeof offsetTop === 'number';
|
|
offsetMode.bottom = typeof this.nzOffsetBottom === 'number';
|
|
}
|
|
const targetRect = getTargetRect(targetNode);
|
|
const targetInnerHeight = targetNode.innerHeight || targetNode.clientHeight;
|
|
if (scrollTop >= elemOffset.top - offsetTop && offsetMode.top) {
|
|
const width = elemOffset.width;
|
|
const top = targetRect.top + offsetTop;
|
|
this.setAffixStyle(e, {
|
|
position: 'fixed',
|
|
top,
|
|
left: targetRect.left + elemOffset.left,
|
|
width
|
|
});
|
|
this.setPlaceholderStyle({
|
|
width,
|
|
height: elemSize.height
|
|
});
|
|
}
|
|
else if (scrollTop <= elemOffset.top + elemSize.height + this.nzOffsetBottom - targetInnerHeight &&
|
|
offsetMode.bottom) {
|
|
const targetBottomOffset = targetNode === window ? 0 : window.innerHeight - targetRect.bottom;
|
|
const width = elemOffset.width;
|
|
this.setAffixStyle(e, {
|
|
position: 'fixed',
|
|
bottom: targetBottomOffset + this.nzOffsetBottom,
|
|
left: targetRect.left + elemOffset.left,
|
|
width
|
|
});
|
|
this.setPlaceholderStyle({
|
|
width,
|
|
height: elemOffset.height
|
|
});
|
|
}
|
|
else {
|
|
if (e.type === AffixRespondEvents.resize &&
|
|
this.affixStyle &&
|
|
this.affixStyle.position === 'fixed' &&
|
|
this.placeholderNode.offsetWidth) {
|
|
this.setAffixStyle(e, {
|
|
...this.affixStyle,
|
|
width: this.placeholderNode.offsetWidth
|
|
});
|
|
}
|
|
else {
|
|
this.setAffixStyle(e);
|
|
}
|
|
this.setPlaceholderStyle();
|
|
}
|
|
if (e.type === 'resize') {
|
|
this.syncPlaceholderStyle(e);
|
|
}
|
|
}
|
|
updateRtlClass() {
|
|
const wrapEl = this.fixedEl.nativeElement;
|
|
if (this.dir === 'rtl') {
|
|
if (wrapEl.classList.contains(NZ_AFFIX_CLS_PREFIX)) {
|
|
wrapEl.classList.add(`${NZ_AFFIX_CLS_PREFIX}-rtl`);
|
|
}
|
|
else {
|
|
wrapEl.classList.remove(`${NZ_AFFIX_CLS_PREFIX}-rtl`);
|
|
}
|
|
}
|
|
else {
|
|
wrapEl.classList.remove(`${NZ_AFFIX_CLS_PREFIX}-rtl`);
|
|
}
|
|
}
|
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzAffixComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "20.3.0", type: NzAffixComponent, isStandalone: true, selector: "nz-affix", inputs: { nzTarget: "nzTarget", nzOffsetTop: ["nzOffsetTop", "nzOffsetTop", numberAttributeWithZeroFallback], nzOffsetBottom: ["nzOffsetBottom", "nzOffsetBottom", numberAttributeWithZeroFallback] }, outputs: { nzChange: "nzChange" }, viewQueries: [{ propertyName: "fixedEl", first: true, predicate: ["fixedEl"], descendants: true, static: true }], exportAs: ["nzAffix"], usesOnChanges: true, ngImport: i0, template: `
|
|
<div #fixedEl>
|
|
<ng-content></ng-content>
|
|
</div>
|
|
`, isInline: true, dependencies: [{ kind: "ngmodule", type: BidiModule }, { kind: "ngmodule", type: PlatformModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
};
|
|
})();
|
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzAffixComponent, decorators: [{
|
|
type: Component,
|
|
args: [{
|
|
selector: 'nz-affix',
|
|
exportAs: 'nzAffix',
|
|
imports: [BidiModule, PlatformModule],
|
|
template: `
|
|
<div #fixedEl>
|
|
<ng-content></ng-content>
|
|
</div>
|
|
`,
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
encapsulation: ViewEncapsulation.None
|
|
}]
|
|
}], ctorParameters: () => [], propDecorators: { fixedEl: [{
|
|
type: ViewChild,
|
|
args: ['fixedEl', { static: true }]
|
|
}], nzTarget: [{
|
|
type: Input
|
|
}], nzOffsetTop: [{
|
|
type: Input,
|
|
args: [{ transform: numberAttributeWithZeroFallback }]
|
|
}], nzOffsetBottom: [{
|
|
type: Input,
|
|
args: [{ transform: numberAttributeWithZeroFallback }]
|
|
}], nzChange: [{
|
|
type: Output
|
|
}] } });
|
|
|
|
/**
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
|
|
*/
|
|
class NzAffixModule {
|
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzAffixModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.0", ngImport: i0, type: NzAffixModule, imports: [NzAffixComponent], exports: [NzAffixComponent] });
|
|
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzAffixModule, imports: [NzAffixComponent] });
|
|
}
|
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.0", ngImport: i0, type: NzAffixModule, decorators: [{
|
|
type: NgModule,
|
|
args: [{
|
|
exports: [NzAffixComponent],
|
|
imports: [NzAffixComponent]
|
|
}]
|
|
}] });
|
|
|
|
/**
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
|
|
*/
|
|
|
|
/**
|
|
* Generated bundle index. Do not edit.
|
|
*/
|
|
|
|
export { NzAffixComponent, NzAffixModule };
|
|
//# sourceMappingURL=ng-zorro-antd-affix.mjs.map
|