@@ -908,6 +908,24 @@ export class ComponentDecoratorHandler
908908 }
909909 }
910910
911+ // Check for ng-content in IsolatedShadowDom components
912+ if ( encapsulation === ViewEncapsulation . ExperimentalIsolatedShadowDom ) {
913+ const contentNode = findContentNode ( template . nodes ) ;
914+ if ( contentNode !== null ) {
915+ if ( diagnostics === undefined ) {
916+ diagnostics = [ ] ;
917+ }
918+ diagnostics . push (
919+ makeDiagnostic (
920+ ErrorCode . ISOLATED_SHADOW_DOM_INVALID_CONTENT_PROJECTION ,
921+ component . get ( 'template' ) ?? node . name ,
922+ `ng-content projection is not supported with ViewEncapsulation.ExperimentalIsolatedShadowDom. ` +
923+ `Use native <slot> elements instead. Content will remain in the light DOM and be projected via slots.` ,
924+ ) ,
925+ ) ;
926+ }
927+ }
928+
911929 // If inline styles were preprocessed use those
912930 let inlineStyles : string [ ] | null = null ;
913931 if ( this . preanalyzeStylesCache . has ( node ) ) {
@@ -2637,3 +2655,24 @@ function validateStandaloneImports(
26372655function isDefaultImport ( node : ts . ImportDeclaration ) : boolean {
26382656 return node . importClause !== undefined && node . importClause . namedBindings === undefined ;
26392657}
2658+
2659+ /**
2660+ * Recursively searches through template nodes to find a Content node (ng-content).
2661+ * Returns the first Content node found, or null if none exist.
2662+ */
2663+ function findContentNode ( nodes : any [ ] ) : any | null {
2664+ for ( const node of nodes ) {
2665+ // Check if this is a Content node (ng-content)
2666+ if ( node . name === 'ng-content' ) {
2667+ return node ;
2668+ }
2669+ // Recursively check children
2670+ if ( node . children && node . children . length > 0 ) {
2671+ const found = findContentNode ( node . children ) ;
2672+ if ( found !== null ) {
2673+ return found ;
2674+ }
2675+ }
2676+ }
2677+ return null ;
2678+ }
0 commit comments