fine-true
Version:
A small and beautiful Vue3 version of the UI Library
80 lines (72 loc) • 2.02 kB
text/typescript
import { InjectionKey } from 'vue';
type PopoverProvideType = {
getSourceEl: (el: HTMLElement) => void;
getTargetEl: (el: HTMLElement) => void;
};
export const POPOVERPROVIDEKEY: InjectionKey<PopoverProvideType> = Symbol(
'popover-provide-key'
);
export const placements = [
'top',
'top-start',
'top-end',
'bottom',
'bottom-start',
'bottom-end',
'left',
'left-start',
'left-end',
'right',
'right-start',
'right-end',
] as const;
export type PlacementType = typeof placements[number];
export const triggers = ['click', 'hover', 'focus', 'contextmenu'] as const;
export type TriggerType = typeof triggers[number];
const throllte = (fn: any, times: number = 20) => {
let startTime = 0;
return (context: any = window) => {
let endTime = Date.now();
if (endTime - startTime > times) {
startTime = endTime;
fn.call(context);
}
};
};
export const getLastNotTextChild = (
childs: any //Array<{ el: HTMLElement; [key: string]: any }>
) => {
let last = null;
let i = childs.length;
if (!i) return last;
while (i--) {
const item = childs[i];
if (item.nodeType === 1) {
return item;
}
}
return null;
};
const getScrollContainers = (el: HTMLElement) => {
let parent = el.parentNode;
let scrollContainers = [];
while (parent) {
if (['BODY', 'HTML', '#document'].includes(parent.nodeName)) {
scrollContainers.push(parent);
} else if (/scroll|auto/.test(getComputedStyle(parent as any).overflow)) {
scrollContainers.push(parent);
}
parent = parent.parentNode;
}
return scrollContainers;
};
const onWatchScroll = (containers: ParentNode[], fn: () => void) => {
containers.forEach((dom) => {
(dom as Element).addEventListener('scroll', fn);
});
};
const offWatchScroll = (containers: ParentNode[], fn: () => void) => {
containers.forEach((dom) => {
(dom as Element).removeEventListener('scroll', fn);
});
};