Skip to content
This repository has been archived by the owner on Dec 10, 2022. It is now read-only.

Commit

Permalink
feat(preset): Implement Preset decorator
Browse files Browse the repository at this point in the history
And make preset type as abstract class so we can validate all presets
  • Loading branch information
gund committed Jan 10, 2018
1 parent cc5c72f commit feefd29
Show file tree
Hide file tree
Showing 21 changed files with 277 additions and 128 deletions.
9 changes: 3 additions & 6 deletions src/demo/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,14 @@ import { MyCustomModule } from './my/my-custom.module';
import { MyModule } from './my/my.module';

@NgModule({
declarations: [
AppComponent,
MyPresetOneComponent,
],
declarations: [AppComponent, MyPresetOneComponent],
imports: [
BrowserModule,
MyModule, // This is normal use-case
// MyCustomModule.withPreset(MyPresetOneComponent), // Uncomment this
// to override default preset
],
providers: [],
bootstrap: [AppComponent]
bootstrap: [AppComponent],
})
export class AppModule { }
export class AppModule {}
4 changes: 2 additions & 2 deletions src/demo/my-preset-one/my-preset-one.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { MyPreset } from '../my/my-preset';
@Component({
selector: 'prst-my-preset-one',
templateUrl: './my-preset-one.component.html',
styleUrls: ['./my-preset-one.component.css']
styleUrls: ['./my-preset-one.component.css'],
})
export class MyPresetOneComponent implements MyPreset {
export class MyPresetOneComponent extends MyPreset {
@ViewChild('headerTpl') headerTpl: TemplateRef<any>;
@ViewChild('contentTpl') contentTpl: TemplateRef<any>;
@ViewChild('footerTpl') footerTpl: TemplateRef<any>;
Expand Down
8 changes: 2 additions & 6 deletions src/demo/my/my-custom.module.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import { ModuleWithProviders, NgModule, Type } from '@angular/core';

import { PresetModule } from '../../preset';
import { providePresetFor } from '../../preset/preset-method';
import { PresetModule, providePresetFor } from '../../preset';
import { MyComponentModule } from './my-component.module';
import { MyPreset } from './my-preset';
import { MyComponent } from './my.component';

@NgModule({
imports: [
MyComponentModule,
PresetModule.forComponent(MyComponent),
],
imports: [MyComponentModule, PresetModule.forComponent(MyComponent)],
exports: [MyComponentModule],
})
export class MyCustomModule {
Expand Down
4 changes: 2 additions & 2 deletions src/demo/my/my-preset-default/my-preset-default.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { MyPreset } from '../my-preset';
@Component({
selector: 'prst-my-preset-default',
templateUrl: './my-preset-default.component.html',
styleUrls: ['./my-preset-default.component.css']
styleUrls: ['./my-preset-default.component.css'],
})
export class MyPresetDefaultComponent implements MyPreset {
export class MyPresetDefaultComponent extends MyPreset {
@ViewChild('headerTpl') headerTpl: TemplateRef<any>;
@ViewChild('contentTpl') contentTpl: TemplateRef<any>;
@ViewChild('footerTpl') footerTpl: TemplateRef<any>;
Expand Down
4 changes: 3 additions & 1 deletion src/demo/my/my-preset.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { TemplateRef } from '@angular/core';

export interface MyPreset {
import { PresetType } from '../../preset';

export abstract class MyPreset extends PresetType {
headerTpl: TemplateRef<any>;
contentTpl: TemplateRef<any>;
footerTpl: TemplateRef<any>;
Expand Down
12 changes: 3 additions & 9 deletions src/demo/my/my.component.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
import { Component } from '@angular/core';

import { PresetService } from '../../preset';
import { Preset } from '../../preset';
import { MyPreset } from './my-preset';

@Component({
selector: 'prst-my',
templateUrl: './my.component.html',
styleUrls: ['./my.component.css']
styleUrls: ['./my.component.css'],
})
export class MyComponent {

presetComp = this.presetService.getPreset<MyPreset>();

constructor(
private presetService: PresetService,
) { }

@Preset() presetComp: MyPreset;
}
3 changes: 2 additions & 1 deletion src/preset/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export { PresetType } from './preset-token';
export * from './preset-method';
export * from './provide';
export * from './metadata';
export * from './preset.service';
export * from './preset.module';
export * from './preset-default.module';
1 change: 1 addition & 0 deletions src/preset/metadata/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './preset';
34 changes: 34 additions & 0 deletions src/preset/metadata/preset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export const PRESET_METADATA_KEY = '__Preset-Key__';

export interface PresetMetadata {
propName: string | symbol;
options?: PresetMetadataOptions;
}

// tslint:disable-next-line:no-empty-interface
export interface PresetMetadataOptions {}

export function setPresetMetadataOn(
type: any,
metadata: PresetMetadata | PresetMetadata[],
) {
if (!Array.isArray(metadata)) {
metadata = [metadata];
}

const ctor = type.constructor;
const existingMetadata = ctor[PRESET_METADATA_KEY] || [];
ctor[PRESET_METADATA_KEY] = [...existingMetadata, ...metadata];
}

export function getPresetMetadataFrom(type: any): PresetMetadata[] {
return type[PRESET_METADATA_KEY] || [];
}

export function Preset(options?: PresetMetadataOptions): PropertyDecorator {
return (target, propName) =>
setPresetMetadataOn(target, {
propName,
options,
});
}
19 changes: 14 additions & 5 deletions src/preset/preset-default.module.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { PRESET_COMPS_TOKEN } from './preset-token';
import { CommonModule } from '@angular/common';
import { ModuleWithProviders, NgModule, Type } from '@angular/core';

import { providePresetFor } from './preset-method';
import { providePresetFor } from './provide/preset-for';
import { PresetService } from './preset.service';

@NgModule({
Expand All @@ -11,15 +12,23 @@ import { PresetService } from './preset.service';
providers: [PresetService],
})
export class PresetDefaultModule {

static forComponent(component: Type<any>, presetType: Type<any>): ModuleWithProviders {
static forComponent(
component: Type<any>,
presetType: Type<any>,
): ModuleWithProviders {
return PresetDefaultModule.forComponents([component], presetType);
}

static forComponents(components: Type<any>[], presetType: Type<any>): ModuleWithProviders {
static forComponents(
components: Type<any>[],
presetType: Type<any>,
): ModuleWithProviders {
return providePresetFor(PresetDefaultModule, presetType, [
{ provide: 'COMPS', useValue: components, multi: true },
{ provide: PRESET_COMPS_TOKEN, useValue: components, multi: true },
]);
}

constructor(presetService: PresetService) {
presetService.initDecoratedPresets();
}
}
38 changes: 0 additions & 38 deletions src/preset/preset-method.spec.ts

This file was deleted.

40 changes: 0 additions & 40 deletions src/preset/preset-method.ts

This file was deleted.

10 changes: 7 additions & 3 deletions src/preset/preset-token.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { InjectionToken, Type } from '@angular/core';

// tslint:disable-next-line:no-empty-interface
export interface PresetType<T = any> extends Type<T> { }
export abstract class PresetType {}

export const PRESET_TYPES_TOKEN = new InjectionToken<PresetType[]>('PresetTypes');
export const PRESET_TYPES_TOKEN = new InjectionToken<PresetType[]>(
'PresetTypes',
);
export const PRESET_COMPS_TOKEN = new InjectionToken<Type<any>[][]>(
'PresetComps',
);
7 changes: 5 additions & 2 deletions src/preset/preset.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { CommonModule } from '@angular/common';
import { ModuleWithProviders, NgModule, Type } from '@angular/core';

import { PRESET_COMPS_TOKEN } from './preset-token';
import { PresetService } from './preset.service';

@NgModule({
Expand All @@ -10,7 +11,6 @@ import { PresetService } from './preset.service';
providers: [PresetService],
})
export class PresetModule {

static forComponent(component: Type<any>): ModuleWithProviders {
return PresetModule.forComponents([component]);
}
Expand All @@ -19,9 +19,12 @@ export class PresetModule {
return {
ngModule: PresetModule,
providers: [
{ provide: 'COMPS', useValue: components, multi: true },
{ provide: PRESET_COMPS_TOKEN, useValue: components, multi: true },
],
};
}

constructor(presetService: PresetService) {
presetService.initDecoratedPresets();
}
}
Loading

0 comments on commit feefd29

Please sign in to comment.