mirror of
https://gitee.com/ant-design-vue/ant-design-vue.git
synced 2024-12-02 03:58:05 +08:00
refactor: affix by ts
This commit is contained in:
parent
f48ccdac01
commit
2185458744
@ -1,4 +1,4 @@
|
||||
import { inject } from 'vue';
|
||||
import { App, CSSProperties, defineComponent, inject } from 'vue';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import classNames from '../_util/classNames';
|
||||
import omit from 'omit.js';
|
||||
@ -18,6 +18,17 @@ import {
|
||||
function getDefaultTarget() {
|
||||
return typeof window !== 'undefined' ? window : null;
|
||||
}
|
||||
enum AffixStatus {
|
||||
None,
|
||||
Prepare,
|
||||
}
|
||||
export interface AffixState {
|
||||
affixStyle?: CSSProperties;
|
||||
placeholderStyle?: CSSProperties;
|
||||
status: AffixStatus;
|
||||
lastAffix: boolean;
|
||||
prevTarget: Window | HTMLElement | null;
|
||||
}
|
||||
|
||||
// Affix
|
||||
const AffixProps = {
|
||||
@ -36,11 +47,7 @@ const AffixProps = {
|
||||
onChange: PropTypes.func,
|
||||
onTestUpdatePosition: PropTypes.func,
|
||||
};
|
||||
const AffixStatus = {
|
||||
None: 'none',
|
||||
Prepare: 'Prepare',
|
||||
};
|
||||
const Affix = {
|
||||
const Affix = defineComponent({
|
||||
name: 'AAffix',
|
||||
props: AffixProps,
|
||||
mixins: [BaseMixin],
|
||||
@ -49,6 +56,7 @@ const Affix = {
|
||||
configProvider: inject('configProvider', defaultConfigProvider),
|
||||
};
|
||||
},
|
||||
emits: ['change', 'testUpdatePosition'],
|
||||
data() {
|
||||
return {
|
||||
affixStyle: undefined,
|
||||
@ -56,6 +64,7 @@ const Affix = {
|
||||
status: AffixStatus.None,
|
||||
lastAffix: false,
|
||||
prevTarget: null,
|
||||
timeout: null,
|
||||
};
|
||||
},
|
||||
beforeMount() {
|
||||
@ -103,9 +112,9 @@ const Affix = {
|
||||
beforeUnmount() {
|
||||
clearTimeout(this.timeout);
|
||||
removeObserveTarget(this);
|
||||
this.updatePosition.cancel();
|
||||
(this.updatePosition as any).cancel();
|
||||
// https://github.com/ant-design/ant-design/issues/22683
|
||||
this.lazyUpdatePosition.cancel();
|
||||
(this.lazyUpdatePosition as any).cancel();
|
||||
},
|
||||
methods: {
|
||||
getOffsetTop() {
|
||||
@ -152,9 +161,9 @@ const Affix = {
|
||||
|
||||
const newState = {
|
||||
status: AffixStatus.None,
|
||||
};
|
||||
} as AffixState;
|
||||
const targetRect = getTargetRect(targetNode);
|
||||
const placeholderReact = getTargetRect(this.$refs.placeholderNode);
|
||||
const placeholderReact = getTargetRect(this.$refs.placeholderNode as HTMLElement);
|
||||
const fixedTop = getFixedTop(placeholderReact, targetRect, offsetTop);
|
||||
const fixedBottom = getFixedBottom(placeholderReact, targetRect, offsetBottom);
|
||||
if (fixedTop !== undefined) {
|
||||
@ -218,7 +227,7 @@ const Affix = {
|
||||
const targetNode = target();
|
||||
if (targetNode && this.$refs.placeholderNode) {
|
||||
const targetRect = getTargetRect(targetNode);
|
||||
const placeholderReact = getTargetRect(this.$refs.placeholderNode);
|
||||
const placeholderReact = getTargetRect(this.$refs.placeholderNode as HTMLElement);
|
||||
const fixedTop = getFixedTop(placeholderReact, targetRect, offsetTop);
|
||||
const fixedBottom = getFixedBottom(placeholderReact, targetRect, offsetBottom);
|
||||
|
||||
@ -256,10 +265,9 @@ const Affix = {
|
||||
</ResizeObserver>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
});
|
||||
/* istanbul ignore next */
|
||||
Affix.install = function(app) {
|
||||
Affix.install = function(app: App) {
|
||||
app.component(Affix.name, Affix);
|
||||
};
|
||||
|
@ -1,22 +1,34 @@
|
||||
import addEventListener from '../vc-util/Dom/addEventListener';
|
||||
import { ComponentPublicInstance } from 'vue';
|
||||
|
||||
export function getTargetRect(target) {
|
||||
export type BindElement = HTMLElement | Window | null | undefined;
|
||||
export type Rect = ClientRect | DOMRect;
|
||||
|
||||
export function getTargetRect(target: BindElement): ClientRect {
|
||||
return target !== window
|
||||
? target.getBoundingClientRect()
|
||||
: { top: 0, bottom: window.innerHeight };
|
||||
? (target as HTMLElement).getBoundingClientRect()
|
||||
: ({ top: 0, bottom: window.innerHeight } as ClientRect);
|
||||
}
|
||||
|
||||
export function getFixedTop(placeholderReact, targetRect, offsetTop) {
|
||||
export function getFixedTop(
|
||||
placeholderReact: Rect,
|
||||
targetRect: Rect,
|
||||
offsetTop: number | undefined,
|
||||
) {
|
||||
if (offsetTop !== undefined && targetRect.top > placeholderReact.top - offsetTop) {
|
||||
return offsetTop + targetRect.top + 'px';
|
||||
return `${offsetTop + targetRect.top}px`;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getFixedBottom(placeholderReact, targetRect, offsetBottom) {
|
||||
export function getFixedBottom(
|
||||
placeholderReact: Rect,
|
||||
targetRect: Rect,
|
||||
offsetBottom: number | undefined,
|
||||
) {
|
||||
if (offsetBottom !== undefined && targetRect.bottom < placeholderReact.bottom + offsetBottom) {
|
||||
const targetBottomOffset = window.innerHeight - targetRect.bottom;
|
||||
return offsetBottom + targetBottomOffset + 'px';
|
||||
return `${offsetBottom + targetBottomOffset}px`;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@ -32,17 +44,26 @@ const TRIGGER_EVENTS = [
|
||||
'load',
|
||||
];
|
||||
|
||||
let observerEntities = [];
|
||||
interface ObserverEntity {
|
||||
target: HTMLElement | Window;
|
||||
affixList: ComponentPublicInstance<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(target, affix) {
|
||||
export function addObserveTarget(
|
||||
target: HTMLElement | Window | null,
|
||||
affix: ComponentPublicInstance<any>,
|
||||
): void {
|
||||
if (!target) return;
|
||||
|
||||
let entity = observerEntities.find(item => item.target === target);
|
||||
let entity: ObserverEntity | undefined = observerEntities.find(item => item.target === target);
|
||||
|
||||
if (entity) {
|
||||
entity.affixList.push(affix);
|
||||
@ -56,16 +77,16 @@ export function addObserveTarget(target, affix) {
|
||||
|
||||
// Add listener
|
||||
TRIGGER_EVENTS.forEach(eventName => {
|
||||
entity.eventHandlers[eventName] = addEventListener(target, eventName, () => {
|
||||
entity.affixList.forEach(targetAffix => {
|
||||
targetAffix.lazyUpdatePosition();
|
||||
entity!.eventHandlers[eventName] = addEventListener(target, eventName, () => {
|
||||
entity!.affixList.forEach(targetAffix => {
|
||||
(targetAffix as any).lazyUpdatePosition();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function removeObserveTarget(affix) {
|
||||
export function removeObserveTarget(affix: ComponentPublicInstance<any>): void {
|
||||
const observerEntity = observerEntities.find(oriObserverEntity => {
|
||||
const hasAffix = oriObserverEntity.affixList.some(item => item === affix);
|
||||
if (hasAffix) {
|
@ -2,8 +2,7 @@
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"ant-design-vue": ["components/index.tsx"],
|
||||
"ant-design-vue/es/*": ["components/*"]
|
||||
"ant-design-vue": ["components/index.tsx"]
|
||||
},
|
||||
"strictNullChecks": false,
|
||||
"strict": true,
|
||||
|
Loading…
Reference in New Issue
Block a user