Skip to content

Commit

Permalink
feat(dom): add support for instanceConfig (#384)
Browse files Browse the repository at this point in the history
  • Loading branch information
fahrradflucht authored Feb 27, 2019
1 parent c82947c commit 19555ed
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 21 deletions.
46 changes: 35 additions & 11 deletions packages/dom/src/feature-app-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,59 @@ export interface DomFeatureApp {
attachTo(container: Element): void;
}

const elementName = 'feature-app-container';

/**
* Define a custom element named `feature-app-container` at the
* `CustomElementRegistry`.
*
* The defined element has a `featureAppDefinition` property which needs to be
* set to a `FeatureAppDefinition` for a {@link DomFeatureApp} and an optional
* `idSpecifier` attribute which needs to be defined if multiple instances of
* the same Feature App are placed on a single web page.
* A custom element defined by {@link defineFeatureAppContainer} as
* `feature-app-container`.
*
* It is possible to pass a slot named `error` to the `feature-app-container`
* element which is rendered if the Feature App could not be created or if the
* Feature App throws in its {@link DomFeatureApp.attachTo} method.
*/
export interface FeatureAppContainerElement extends HTMLElement {
/**
* The definition of the Feature App that should be rendered.
*/
featureAppDefinition?: FeatureAppDefinition<DomFeatureApp>;

/**
* If multiple instances of the same Feature App are placed on a single web
* page, an `idSpecifier` that is unique for the Feature App ID must be
* defined.
*/
idSpecifier?: string;

/**
* A config object that is intended for the specific Feature App instance
* that the `feature-app-container` renders.
*/
instanceConfig?: unknown;
}

const elementName = 'feature-app-container';

/**
* Define a custom element implementing the {@link FeatureAppContainerElement}
* interface under the name `feature-app-container` at the
* `CustomElementRegistry`.
*/
export function defineFeatureAppContainer(
featureAppManager: FeatureAppManager
): void {
if (customElements.get(elementName)) {
return;
}

class FeatureAppContainer extends LitElement {
class FeatureAppContainer extends LitElement
implements FeatureAppContainerElement {
@property({type: Object})
public featureAppDefinition?: FeatureAppDefinition<DomFeatureApp>;

@property({type: String})
public idSpecifier?: string;

@property({type: Object})
public instanceConfig?: unknown;

private featureAppScope: FeatureAppScope<DomFeatureApp> | undefined;

public render(): TemplateResult {
Expand All @@ -61,7 +85,7 @@ export function defineFeatureAppContainer(

this.featureAppScope = featureAppManager.getFeatureAppScope(
this.featureAppDefinition,
{idSpecifier: this.idSpecifier}
{idSpecifier: this.idSpecifier, instanceConfig: this.instanceConfig}
);

this.featureAppScope.featureApp.attachTo(element);
Expand Down
44 changes: 34 additions & 10 deletions packages/dom/src/feature-app-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,39 @@ import {defineFeatureAppContainer} from './feature-app-container';
const elementName = 'feature-app-loader';

/**
* Define a custom element named `feature-app-loader` at the
* `CustomElementRegistry`.
*
* The defined element has two attributes, a `src` attribute which needs to
* contain a URL pointing to a Feature App's module bundle and an optional
* `idSpecifier` attribute which needs to be defined if multiple instances of
* the same Feature App are placed on a single web page.
* A custom element defined by {@link defineFeatureAppLoader} as
* `feature-app-loader`.
*
* It is possible to pass two slots to the `feature-app-loader` element. One
* slot named `loading` is rendered while the Feature App module is loading.
* The other one named `error` is rendered if the Feature App module could not
* be loaded and is also passed to the underlying `feature-app-container`
* element (@see {@link defineFeatureAppContainer}).
* element (@see {@link FeatureAppContainerElement}).
*/
export interface FeatureAppLoaderElement extends HTMLElement {
/**
* A URL pointing to a Feature App's module bundle.
*/
src: string;

/**
* If multiple instances of the same Feature App are placed on a single web
* page, an `idSpecifier` that is unique for the Feature App ID must be
* defined.
*/
idSpecifier?: string;

/**
* A config object that is intended for the specific Feature App instance that
* the `feature-app-loader` loads.
*/
instanceConfig?: unknown;
}

/**
* Define a custom element implementing the {@link FeatureAppLoaderElement}
* interface under the name `feature-app-loader` at the
* `CustomElementRegistry`.
*/
export function defineFeatureAppLoader(
featureAppManager: FeatureAppManager
Expand All @@ -30,12 +50,15 @@ export function defineFeatureAppLoader(

defineFeatureAppContainer(featureAppManager);

class FeatureAppLoader extends LitElement {
class FeatureAppLoader extends LitElement implements FeatureAppLoaderElement {
@property({type: String})
public src!: string;

@property({type: String})
public idSpecifier: string | undefined;
public idSpecifier?: string;

@property({type: Object})
public instanceConfig?: unknown;

public render(): TemplateResult {
return html`
Expand All @@ -62,6 +85,7 @@ export function defineFeatureAppLoader(
<feature-app-container
idSpecifier=${this.idSpecifier}
.featureAppDefinition=${definition}
.instanceConfig=${this.instanceConfig}
>
<slot name="error" slot="error"></slot>
</feature-app-container>
Expand Down

0 comments on commit 19555ed

Please sign in to comment.