ant-design-vue/components/affix/utils.ts
一堆菠萝 975d70e7ed
fix: some type & doc (#6292)
* fix: typo (#6218)

* fix:  typo

* docs<upload>: docs update

* fix: type of minute in props disabledDateTime of DatePicker (#6233)

* docs: typo (#6256)

* feat: tooltip added overlayInnerStyle attribute

* Update abstractTooltipProps.ts

* Update Tooltip.tsx

---------

Co-authored-by: lyn <76365499@qq.com>
Co-authored-by: H1mple <35363759+baohangxing@users.noreply.github.com>
Co-authored-by: tangjinzhou <415800467@qq.com>
2023-02-21 14:10:35 +08:00

108 lines
3.0 KiB
TypeScript

import addEventListener from '../vc-util/Dom/addEventListener';
import supportsPassive from '../_util/supportsPassive';
export type BindElement = HTMLElement | Window | null | undefined;
export function getTargetRect(target: BindElement): DOMRect {
return target !== window
? (target as HTMLElement).getBoundingClientRect()
: ({ top: 0, bottom: window.innerHeight } as DOMRect);
}
export function getFixedTop(placeholderRect: DOMRect, targetRect: DOMRect, offsetTop: number) {
if (offsetTop !== undefined && targetRect.top > placeholderRect.top - offsetTop) {
return `${offsetTop + targetRect.top}px`;
}
return undefined;
}
export function getFixedBottom(
placeholderRect: DOMRect,
targetRect: DOMRect,
offsetBottom: number,
) {
if (offsetBottom !== undefined && targetRect.bottom < placeholderRect.bottom + offsetBottom) {
const targetBottomOffset = window.innerHeight - targetRect.bottom;
return `${offsetBottom + targetBottomOffset}px`;
}
return undefined;
}
// ======================== Observer ========================
const TRIGGER_EVENTS = [
'resize',
'scroll',
'touchstart',
'touchmove',
'touchend',
'pageshow',
'load',
];
interface ObserverEntity {
target: HTMLElement | Window;
affixList: any[];
eventHandlers: { [eventName: string]: any };
}
let observerEntities: ObserverEntity[] = [];
export function getObserverEntities() {
// Only used in test env. Can be removed if refactor.
return observerEntities;
}
export function addObserveTarget<T>(target: HTMLElement | Window | null, affix: T): void {
if (!target) return;
let entity = observerEntities.find(item => item.target === target);
if (entity) {
entity.affixList.push(affix);
} else {
entity = {
target,
affixList: [affix],
eventHandlers: {},
};
observerEntities.push(entity);
// Add listener
TRIGGER_EVENTS.forEach(eventName => {
entity!.eventHandlers[eventName] = addEventListener(target, eventName, () => {
entity!.affixList.forEach(
targetAffix => {
const { lazyUpdatePosition } = (targetAffix as any).exposed;
lazyUpdatePosition();
},
(eventName === 'touchstart' || eventName === 'touchmove') && supportsPassive
? ({ passive: true } as EventListenerOptions)
: false,
);
});
});
}
}
export function removeObserveTarget<T>(affix: T): void {
const observerEntity = observerEntities.find(oriObserverEntity => {
const hasAffix = oriObserverEntity.affixList.some(item => item === affix);
if (hasAffix) {
oriObserverEntity.affixList = oriObserverEntity.affixList.filter(item => item !== affix);
}
return hasAffix;
});
if (observerEntity && observerEntity.affixList.length === 0) {
observerEntities = observerEntities.filter(item => item !== observerEntity);
// Remove listener
TRIGGER_EVENTS.forEach(eventName => {
const handler = observerEntity.eventHandlers[eventName];
if (handler && handler.remove) {
handler.remove();
}
});
}
}