60 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
			
		
		
	
	
			60 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
| import type { InjectionKey, Ref } from 'vue';
 | |
| import { computed, inject, provide } from 'vue';
 | |
| export interface TriggerContextProps {
 | |
|   setPortal: (val?: any) => void;
 | |
|   popPortal: boolean; // ๅฐ portal ไธไผ ่ณ็ถ็บงๅ
็ด ๆธฒๆ๏ผไธ็จ่่ๅๅบๅผ
 | |
| }
 | |
| const TriggerContextKey: InjectionKey<TriggerContextProps> = Symbol('TriggerContextKey');
 | |
| export const useProviderTrigger = () => {
 | |
|   let portal = null;
 | |
|   provide(TriggerContextKey, {
 | |
|     setPortal(val) {
 | |
|       portal = val;
 | |
|     },
 | |
|     popPortal: true,
 | |
|   });
 | |
|   return () => {
 | |
|     return portal;
 | |
|   };
 | |
| };
 | |
| 
 | |
| export const useInjectTrigger = () => {
 | |
|   return inject(TriggerContextKey, { setPortal: () => {}, popPortal: false });
 | |
| };
 | |
| 
 | |
| 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,
 | |
|     ),
 | |
|   };
 | |
| };
 |