diff --git a/components/affix/index.jsx b/components/affix/index.tsx similarity index 92% rename from components/affix/index.jsx rename to components/affix/index.tsx index b38d2dd65..711a234c2 100644 --- a/components/affix/index.jsx +++ b/components/affix/index.tsx @@ -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 = { ); }, -}; - +}); /* istanbul ignore next */ -Affix.install = function(app) { +Affix.install = function(app: App) { app.component(Affix.name, Affix); }; diff --git a/components/affix/utils.js b/components/affix/utils.ts similarity index 55% rename from components/affix/utils.js rename to components/affix/utils.ts index 52876ae97..898f8d68d 100644 --- a/components/affix/utils.js +++ b/components/affix/utils.ts @@ -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[]; + 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, +): 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): void { const observerEntity = observerEntities.find(oriObserverEntity => { const hasAffix = oriObserverEntity.affixList.some(item => item === affix); if (hasAffix) { diff --git a/tsconfig.json b/tsconfig.json index deaedc68a..52bce7dcf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -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,