import { defineComponent , h , ref , onErrorCaptured , inject , getCurrentInstance } from 'vue' ; import { ComponentRendering , RouteData , Field , Item } from '@sitecore-jss/sitecore-jss/layout' ; import { convertVNodesToDynamicComponents , getPlaceholderDataFromRenderingData , getVNodesForRenderingData , PlaceholderProps , } from './PlaceholderCommon' ; import { ComponentFactory } from './sharedTypes' ; export { PlaceholderProps } ; export const Placeholder = defineComponent ( { name : 'Placeholder' , inheritAttrs : false , type { PlaceholderProps } props : { name : { type : String , required : true , } , rendering : { type : Object as ( ) => ComponentRendering | RouteData , required : true , } , componentFactory : { type : Object as ( ) => ComponentFactory , default : undefined , } , fields : { type : Object as ( ) => { [ name ] : Field | Item [ ] ; } , default : undefined , } , params : { type : Object as ( ) => { [ name ] : string ; } , default : undefined , } , missingComponentComponent : { type : Object , default : undefined , } , hiddenRenderingComponent : { type : Object , default : undefined , } , errorComponent : { type : Object , default : undefined , } , } , setup ( props , context ) { const instance = getCurrentInstance ( ) ; const injectedComponentFactory = inject < ComponentFactory > ( 'injectedComponentFactory' , null ) ; const error = ref < Error > ( ) ; onErrorCaptured ( ( err ) => { error . value = err as Error ; } ) ; const resolveComponentFactory = ( ) : ComponentFactory | undefined => { return ( props . componentFactory || injectedComponentFactory || ( instance && instance . appContext . config . globalProperties . $jss && instance . appContext . config . globalProperties . $jss . componentFactory ) || undefined ) ; } ; const childProps = { ... props , ... context . attrs , } as PlaceholderProps ; delete childProps . componentFactory ; if ( error . value ) { if ( props . errorComponent ) { return ( ) => h ( props . errorComponent , { props : { error : error . value } , } ) ; } return ( ) => h ( 'div' , { class : 'sc-jss-placeholder-error' } , error . value . toString ( ) ) ; } const placeholderData = getPlaceholderDataFromRenderingData ( props . rendering as any , props . name ) ; const componentFactory = resolveComponentFactory ( ) ; const vnodes = getVNodesForRenderingData ( placeholderData , childProps , componentFactory ) ; const scopedSlots = context . slots ; if ( scopedSlots . default ) { const components = convertVNodesToDynamicComponents ( vnodes ) ; const isEmpty = components . every ( ( component ) => component . isxEditorComponent ? true : false ) ; return ( ) => scopedSlots . default ( { components , isEmpty } ) ; } return ( ) => ( vnodes && vnodes . length > 0 ? vnodes : null ) ; } , } ) ;