@opensig/opendesign
Version:
91 lines (90 loc) • 3.56 kB
TypeScript
import { Ref } from 'vue';
import { PopupPositionT, PopupTriggerT } from './types';
/**
* popup 视口坐标 (builder 阶段输出 / flip 阶段修改 / clamp 阶段调整 / wrap 阶段输出 transform)。
*
* 12 个 position 统一语义:
* - `left` = 视口坐标的弹层左边缘 X
* - `top` = 视口坐标的弹层顶边 Y
*
* `transform` 字段仅在 `getPopupWrapOffset` 输出阶段存在 (wrapper 坐标系下的 transform 像素值),
* builder 阶段不输出, flip/clamp 阶段不修改。
*/
interface Pos {
/** 视口坐标的弹层左边缘 X */
left: number;
/** 视口坐标的弹层顶边 Y */
top: number;
}
interface AnchorPosition {
left?: string;
top?: string;
right?: string;
bottom?: string;
}
/** calcPopupStyle 的可选项 */
interface CalcPopupStyleOptions {
/** popup 元素 */
popupEl: HTMLElement;
/** target 元素 */
targetEl: HTMLElement;
/** popup 位置 */
position: PopupPositionT;
/** 自适应容器边缘 */
adaptive?: boolean;
/** 是否计算 anchor 位置 */
anchor?: boolean;
/** anchor 距弹层边缘的最小距离 */
anchorOffset?: number;
/** popup 距离 target 的偏移 */
offset?: number;
/** popup 与容器边缘的最小距离 */
edgeOffset?: number;
}
/**
* 计算 popup 最终的位置与样式 (含自适应翻转、anchor 位置、wrapper 坐标转换)。
*
* pSize 在入口读取一次, 整轮 calc 冻结: viewOffsetBuilders (依赖 pSize 的 10 个 builder)
* 与 adjustOffset 内的 flip/clamp 共享同一份 pSize, 避免写出的 popStyle 触发 CSS
* shrink-to-fit 重新收敛导致 pSize 漂移。
*
* @param opts - 配置项 (popupEl / targetEl / position / adaptive / anchor / anchorOffset / offset / edgeOffset)
* @returns popup 最终的位置、样式、anchor 位置与是否翻转
* @todo getBoundingClientRect 与 offsetWidth clientWidth 混用可能在有 scale 时产生问题
*/
export declare function calcPopupStyle({ popupEl, targetEl, position, adaptive, anchor, anchorOffset, offset, edgeOffset, }: CalcPopupStyleOptions): {
popupStyle: Pos;
position: "left" | "right" | "top" | "bottom" | "br" | "rt" | "tr" | "rb" | "tl" | "bl" | "lt" | "lb";
anchorStyle: AnchorPosition;
};
/** bindTrigger 的可选项 */
interface BindTriggerOptions {
/** 触发元素, null 时不绑定 */
el: HTMLElement | null;
/** popup ref, 用于判断外部点击是否在 popup 内 */
popupRef: Ref<HTMLElement | null>;
/** 触发器类型列表 */
triggers: PopupTriggerT[];
/** 控制 popup 显隐, 可选 delay 用于 hover 延时 */
updateFn: (isVisible?: boolean, delay?: number) => void;
/** hover 触发延迟 (毫秒) */
hoverDelay?: number;
/** 是否在触发元素外点击或离开时自动隐藏 */
autoHide?: boolean;
}
/**
* 为触发元素绑定不同 trigger 类型对应的事件 (hover/click/focus/contextmenu 等)
* @param opts - 配置项 (el / popupRef / triggers / updateFn / hoverDelay / autoHide)
* @returns 解绑函数数组
*/
export declare function bindTrigger({ el, popupRef, triggers, updateFn, hoverDelay, autoHide }: BindTriggerOptions): Array<() => void>;
/**
* 返回 popup 在指定 position 下的 transform-origin, 用于动画从触发点展开
* @param position - popup 位置
* @returns 水平/垂直方向上的 transform-origin 百分比
*/
export declare function getTransformOrigin(position: PopupPositionT): {
left: string;
top: string;
};
export {};