You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
39 lines
1.2 KiB
39 lines
1.2 KiB
import type { InjectionKey, Ref } from 'vue';
|
|
import { computed, inject, provide } from 'vue';
|
|
|
|
export interface PortalContextProps {
|
|
shouldRender: Ref<boolean>;
|
|
inTriggerContext: boolean; // 仅处理 trigger 上下文的 portal
|
|
}
|
|
const PortalContextKey: InjectionKey<PortalContextProps> = Symbol('PortalContextKey');
|
|
export const useProvidePortal = (instance: any, config = { inTriggerContext: true }) => {
|
|
provide(PortalContextKey, {
|
|
inTriggerContext: config.inTriggerContext,
|
|
shouldRender: computed(() => {
|
|
const { sPopupVisible, popupRef, forceRender, autoDestroy } = instance || {};
|
|
// if (popPortal) return true;
|
|
let shouldRender = false;
|
|
if (sPopupVisible || popupRef || forceRender) {
|
|
shouldRender = true;
|
|
}
|
|
if (!sPopupVisible && autoDestroy) {
|
|
shouldRender = false;
|
|
}
|
|
return shouldRender;
|
|
}),
|
|
});
|
|
};
|
|
|
|
export const useInjectPortal = () => {
|
|
useProvidePortal({}, { inTriggerContext: false });
|
|
const portalContext = inject(PortalContextKey, {
|
|
shouldRender: computed(() => false),
|
|
inTriggerContext: false,
|
|
});
|
|
return {
|
|
shouldRender: computed(
|
|
() => portalContext.shouldRender.value || portalContext.inTriggerContext === false,
|
|
),
|
|
};
|
|
};
|