diff --git a/src/compiler/transpile/datacollection/component-decorator.ts b/src/compiler/transpile/datacollection/component-decorator.ts index c787fd8cad1..32c5d2284c1 100644 --- a/src/compiler/transpile/datacollection/component-decorator.ts +++ b/src/compiler/transpile/datacollection/component-decorator.ts @@ -5,7 +5,6 @@ import { getDeclarationParameters, isDecoratorNamed, serializeSymbol } from './u import { getStylesMeta } from './styles-meta'; import ts from 'typescript'; - export function getComponentDecoratorMeta(diagnostics: d.Diagnostic[], checker: ts.TypeChecker, node: ts.ClassDeclaration): d.ComponentMeta | undefined { if (!node.decorators) { return undefined; @@ -50,11 +49,17 @@ It will be removed in future versions. Please use the "hostData()" method instea jsdoc: serializeSymbol(checker, symbol) }; - // normalizeEncapsulation - cmpMeta.encapsulationMeta = - componentOptions.shadow ? ENCAPSULATION.ShadowDom : + // shadow dom options + if(componentOptions.shadow){ + cmpMeta.encapsulationMeta = ENCAPSULATION.ShadowDom + if(isShadowDomOptions(componentOptions.shadow)) { + cmpMeta.shadowRootOptions = componentOptions.shadow; + } + } else { + cmpMeta.encapsulationMeta = componentOptions.scoped ? ENCAPSULATION.ScopedCss : ENCAPSULATION.NoEncapsulation; + } // assetsDir: './somedir' if (componentOptions.assetsDir) { @@ -107,3 +112,7 @@ function getHostMeta(diagnostics: d.Diagnostic[], hostData: d.HostMeta) { return hostData; } + +function isShadowDomOptions(o: any): o is d.ShadowDomOptions { + return o && typeof(o) === 'object'; +} \ No newline at end of file diff --git a/src/compiler/transpile/datacollection/test/component-decorator.spec.ts b/src/compiler/transpile/datacollection/test/component-decorator.spec.ts index a7231e9ec4e..9c3522b9985 100644 --- a/src/compiler/transpile/datacollection/test/component-decorator.spec.ts +++ b/src/compiler/transpile/datacollection/test/component-decorator.spec.ts @@ -53,6 +53,30 @@ describe('component decorator', () => { }); }); + it('shadow encapsulation with options', () => { + let response; + const sourceFilePath = path.resolve(__dirname, './fixtures/component-shadow-w-options'); + gatherMetadata(sourceFilePath, (checker, classNode) => { + response = getComponentDecoratorMeta([], checker, classNode); + }); + + expect(response).toEqual({ + tagNameMeta: 'ion-action-sheet', + hostMeta: {}, + stylesMeta: {}, + encapsulationMeta: ENCAPSULATION.ShadowDom, + shadowRootOptions: { delegatesFocus: true }, + jsdoc: { + documentation: '', + name: 'ActionSheet', + tags: [], + type: 'typeof ActionSheet' + }, + assetsDirsMeta: [], + dependencies: [] + }); + }); + it('scoped encapsulation', () => { let response; const sourceFilePath = path.resolve(__dirname, './fixtures/component-scoped'); diff --git a/src/compiler/transpile/datacollection/test/fixtures/component-shadow-w-options.ts b/src/compiler/transpile/datacollection/test/fixtures/component-shadow-w-options.ts new file mode 100644 index 00000000000..2bcf2ce62e2 --- /dev/null +++ b/src/compiler/transpile/datacollection/test/fixtures/component-shadow-w-options.ts @@ -0,0 +1,8 @@ +import { Component } from '../../../../../index'; + +@Component({ + tag: 'ion-action-sheet', + shadow: { delegatesFocus: true } +}) +class ActionSheet { +} diff --git a/src/core/host-snapshot.ts b/src/core/host-snapshot.ts index 3238de4ed80..82aad6fc85d 100644 --- a/src/core/host-snapshot.ts +++ b/src/core/host-snapshot.ts @@ -47,7 +47,7 @@ export const initHostSnapshot = (domApi: d.DomApi, cmpMeta: d.ComponentMeta, hos // this component is using shadow dom // and this browser supports shadow dom // add the read-only property "shadowRoot" to the host element - domApi.$attachShadow(hostElm, { mode: 'open' }); + domApi.$attachShadow(hostElm, { mode: 'open', ...cmpMeta.shadowRootOptions }); } } diff --git a/src/declarations/component.ts b/src/declarations/component.ts index b689568e8db..0cad7b033d7 100644 --- a/src/declarations/component.ts +++ b/src/declarations/component.ts @@ -28,6 +28,7 @@ export interface ComponentMeta { listenersMeta?: ListenMeta[]; hostMeta?: HostMeta; encapsulationMeta?: number; + shadowRootOptions?: Readonly; assetsDirsMeta?: AssetsMeta[]; componentConstructor?: ComponentConstructor; componentClass?: string; diff --git a/src/declarations/decorators.ts b/src/declarations/decorators.ts index 19800b3992f..bf60832ab34 100644 --- a/src/declarations/decorators.ts +++ b/src/declarations/decorators.ts @@ -13,12 +13,14 @@ export interface ComponentOptions { styleUrls?: string[] | d.ModeStyles; styles?: string; scoped?: boolean; - shadow?: boolean; + shadow?: boolean | ShadowDomOptions; host?: d.HostMeta; assetsDir?: string; assetsDirs?: string[]; } - +export interface ShadowDomOptions { + delegatesFocus?: boolean; +} export interface PropDecorator { (opts?: PropOptions): PropertyDecorator;