Skip to content

Commit

Permalink
feat: added dbxInjectionContext
Browse files Browse the repository at this point in the history
- added dbxInjectionContext, which can act like an *ngIf/*ngSwitch but takes in the usual injection configuration.

BREAKING CHANGE: renamed dbxInjectedContent to dbxInjection, renamed related content
  • Loading branch information
dereekb committed Apr 16, 2022
1 parent 2d75cd3 commit a6ac801
Show file tree
Hide file tree
Showing 47 changed files with 557 additions and 147 deletions.
11 changes: 7 additions & 4 deletions packages/dbx-core/src/lib/injected/injected.component.module.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { DbxInjectedComponent } from './injected.component';
import { DbxInjectionComponent } from './injected.component';
import { DbxInjectionContextDirective } from './injected.context.component';

@NgModule({
imports: [
CommonModule
],
declarations: [
DbxInjectedComponent
DbxInjectionComponent,
DbxInjectionContextDirective
],
exports: [
DbxInjectedComponent
DbxInjectionComponent,
DbxInjectionContextDirective
],
})
export class DbxInjectedComponentModule { }
export class DbxInjectionComponentModule { }
89 changes: 61 additions & 28 deletions packages/dbx-core/src/lib/injected/injected.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { DbxInjectedTemplateConfig, DbxInjectedComponentConfig } from './injected';
import { DbxInjectedComponent } from './injected.component';
import { DbxInjectionTemplateConfig, DbxInjectionComponentConfig } from './injected';
import { DbxInjectionComponent } from './injected.component';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Component, Input, Type, ViewChild } from '@angular/core';
import { Component, Input, Type, ViewChild, OnDestroy } from '@angular/core';
import { By, BrowserModule } from '@angular/platform-browser';
import { DbxInjectedComponentModule } from './injected.component.module';
import { DbxInjectionComponentModule } from './injected.component.module';

const CUSTOM_CONTENT_ID = 'custom-content';
const CUSTOM_CONTENT = 'Custom Content';
Expand All @@ -13,62 +13,70 @@ const CUSTOM_CONTENT = 'Custom Content';
<span id="${CUSTOM_CONTENT_ID}">${CUSTOM_CONTENT}</span>
`
})
class TestInjectedComponentContent { }
class TestInjectionComponentContent implements OnDestroy {

destroyed = false;

ngOnDestroy(): void {
this.destroyed = true;
}

}

@Component({})
abstract class TestInjectedComponent<T = any> {
abstract class TestInjectionComponent<T = any> {

@Input()
config?: DbxInjectedComponentConfig;
config?: DbxInjectionComponentConfig;

@Input()
template?: DbxInjectedTemplateConfig;
template?: DbxInjectionTemplateConfig;

@ViewChild(DbxInjectedComponent, { static: true })
injectedComponent?: DbxInjectedComponent<T>;
@ViewChild(DbxInjectionComponent, { static: true })
injectedComponent?: DbxInjectionComponent<T>;

}

@Component({
template: `
<div dbx-injected-content [config]="config" [template]="template"></div>
<div dbxInjection [config]="config" [template]="template"></div>
`
})
class TestInjectedComponentWithElement<T = any> extends TestInjectedComponent<T> { }
class TestInjectionComponentWithElement<T = any> extends TestInjectionComponent<T> { }

@Component({
template: `
<dbx-injected-content [config]="config" [template]="template"></dbx-injected-content>
<dbx-injection [config]="config" [template]="template"></dbx-injection>
`
})
class TestInjectedComponentWithAttribute<T = any> extends TestInjectedComponent<T> { }
class TestInjectionComponentWithAttribute<T = any> extends TestInjectionComponent<T> { }

describe('DbxInjectedComponent', () => {
describe('DbxInjectionComponent', () => {

beforeEach(async () => {
TestBed.configureTestingModule({
imports: [
BrowserModule,
DbxInjectedComponentModule
DbxInjectionComponentModule
],
declarations: [
TestInjectedComponentContent,
TestInjectedComponentWithElement,
TestInjectedComponentWithAttribute,
TestInjectionComponentContent,
TestInjectionComponentWithElement,
TestInjectionComponentWithAttribute,
],
providers: []
}).compileComponents();
});

buildTestsWithComponentClass(TestInjectedComponentWithElement, 'element');
buildTestsWithComponentClass(TestInjectedComponentWithAttribute, 'attribute');
buildTestsWithComponentClass(TestInjectionComponentWithElement, 'element');
buildTestsWithComponentClass(TestInjectionComponentWithAttribute, 'attribute');

function buildTestsWithComponentClass<C extends TestInjectedComponent>(type: Type<C>, selector: string): void {
function buildTestsWithComponentClass<C extends TestInjectionComponent>(type: Type<C>, selector: string): void {

describe(`selector "${selector}"`, () => {

let testComponent: TestInjectedComponent;
let fixture: ComponentFixture<TestInjectedComponent>;
let testComponent: TestInjectionComponent;
let fixture: ComponentFixture<TestInjectionComponent>;

beforeEach(async () => {
fixture = TestBed.createComponent(type);
Expand All @@ -80,12 +88,16 @@ describe('DbxInjectedComponent', () => {

beforeEach(async () => {
testComponent.config = {
componentClass: TestInjectedComponentContent
componentClass: TestInjectionComponentContent
};

fixture.detectChanges();
});

afterEach(() => {
fixture.destroy();
});

it('should show content', () => {
const anchorElement: HTMLElement = fixture.debugElement.query(By.css(`#${CUSTOM_CONTENT_ID}`)).nativeElement;
expect(anchorElement).not.toBeNull();
Expand All @@ -94,13 +106,34 @@ describe('DbxInjectedComponent', () => {


it('should show destroy the content when config is cleared.', () => {
const anchorElement: HTMLElement = fixture.debugElement.query(By.css(`#${CUSTOM_CONTENT_ID}`)).nativeElement;
expect(anchorElement).not.toBeNull();
expect(anchorElement.textContent).toBe(CUSTOM_CONTENT);
let instance: TestInjectionComponentContent;

testComponent.config = {
componentClass: TestInjectionComponentContent,
init: (x) => {
instance = x;
}
};

fixture.detectChanges();

expect(instance!).toBeDefined();
expect(instance!.destroyed).toBe(false);

// clear the item
testComponent.config = undefined;

fixture.detectChanges();

// check is destroyed
expect(instance!.destroyed).toBe(true);

});

// todo: test injecting data.

// todo: test with template view being defaulted to when config isn't available.

});

});
Expand Down
12 changes: 6 additions & 6 deletions packages/dbx-core/src/lib/injected/injected.component.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { Component, ViewChild, ViewContainerRef, Input } from '@angular/core';
import { DbxInjectedComponentConfig, DbxInjectedTemplateConfig } from './injected';
import { AbstractDbxInjectedDirective } from './injected.directive';
import { DbxInjectionComponentConfig, DbxInjectionTemplateConfig } from './injected';
import { AbstractDbxInjectionDirective } from './injected.directive';
import { Maybe } from '@dereekb/util';

/**
* Component that injects content based on the configuration into the view.
*/
@Component({
selector: 'dbx-injected-content, [dbxInjectedContext], [dbx-injected-content]',
selector: 'dbx-injection, [dbxInjection], [dbx-injection]',
template: `<ng-template #content></ng-template>`
})
export class DbxInjectedComponent<T> extends AbstractDbxInjectedDirective<T> {
export class DbxInjectionComponent<T> extends AbstractDbxInjectionDirective<T> {

@Input()
set config(config: Maybe<DbxInjectedComponentConfig<T>>) {
set config(config: Maybe<DbxInjectionComponentConfig<T>>) {
this.setConfig(config);
}

@Input()
set template(template: Maybe<DbxInjectedTemplateConfig<T>>) {
set template(template: Maybe<DbxInjectionTemplateConfig<T>>) {
this.setTemplate(template);
}

Expand Down
Loading

0 comments on commit a6ac801

Please sign in to comment.