Skip to content

Commit

Permalink
feat: Typed MapTo / LazyMapTo
Browse files Browse the repository at this point in the history
MapTo and LazyMapTo are now typed with a generic extending
MappedComponentProperties. Use the interface MappedComponentProperties,
abstract class AbstractMappedComponent or the any type to fix your
build.

Co-authored-by: Niek Raaijmakers <niek@adobe.com>
Co-authored-by: Cezary Czernecki <czarek.czernecki@gmail.com>
  • Loading branch information
3 people authored Jan 12, 2021
1 parent 36f71d7 commit a2f2e6b
Show file tree
Hide file tree
Showing 16 changed files with 1,604 additions and 1,267 deletions.
2,438 changes: 1,284 additions & 1,154 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
},
"devDependencies": {
"@adobe/aem-spa-component-mapping": "~1.1.0",
"@adobe/aem-spa-page-model-manager": "^1.2.3",
"@adobe/aem-spa-page-model-manager": "~1.3.0",
"@adobe/eslint-config-editorxp": "^1.0.7",
"@angular-devkit/build-angular": "~0.901.12",
"@angular-devkit/build-ng-packagr": "~0.901.12",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*/

import { Component, Input } from '@angular/core';
import { AEMContainerComponent } from '../aem-container/aem-container.component';
import { AEMContainerComponent, AEMContainerComponentProperties } from '../aem-container/aem-container.component';

/**
* @private
Expand All @@ -28,12 +28,59 @@ export const ALLOWED_COMPONENT_TITLE_CLASS_NAMES = 'aem-AllowedComponent--title'
*/
export const ALLOWED_COMPONENT_PLACEHOLDER_CLASS_NAMES = 'aem-AllowedComponent--component cq-placeholder placeholder';

/**
* Component that is allowed to be used on the page by the editor
*/
export interface AllowedComponent {
/**
* Path to the component under apps
*/
path: string;

/**
* Title of the component
*/
title: string;
}

/**
* AllowedComponents collection
*/
export interface AllowedComponents {
applicable: boolean;

/**
* List of allowed components
*/
components: AllowedComponent[];
}

/**
* Properties for the allowed components container
*/
export interface AEMAllowedComponentsContainerComponentProperties extends AEMContainerComponentProperties {
/**
* List of allowed components for the container
*/
allowedComponents: AllowedComponents;

/**
* Label to display when there are no allowed components
*/
_allowedComponentPlaceholderListEmptyLabel?: string;

/**
* Title of the placeholder list
*/
title: string;
}

@Component({
selector: 'aem-allowed-components-container',
templateUrl: './aem-allowed-components-container.component.html',
styleUrls: [ './aem-allowed-components-container.component.css' ]
})
export class AEMAllowedComponentsContainerComponent extends AEMContainerComponent {
export class AEMAllowedComponentsContainerComponent extends AEMContainerComponent implements AEMAllowedComponentsContainerComponentProperties{

@Input() title: string;

Expand Down
10 changes: 6 additions & 4 deletions src/lib/layout/aem-component.directive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
import { AEMComponentDirective } from './aem-component.directive';
import { Component, Input } from '@angular/core';
import { ComponentMapping, MapTo, LazyMapTo} from './component-mapping';
import { ComponentMapping, MapTo, LazyMapTo, AbstractMappedComponent } from './component-mapping';
import { Utils } from './utils';
import { LazyComponentType } from "../test/lazy-component-wrapper/lazy.component";

@Component({
selector: 'test-component',
Expand All @@ -25,6 +26,7 @@ class AEMDirectiveTestComponent {
@Input() data;
}


@Component({
selector: 'directive-component',
host: {
Expand All @@ -34,16 +36,16 @@ class AEMDirectiveTestComponent {
},
template: `<div></div>`
})
class DirectiveComponent {
class DirectiveComponent extends AbstractMappedComponent {
@Input() attr1;
@Input() attr2;

get hostClasses() {
return 'component-class';
}
}
MapTo('directive/comp')(DirectiveComponent);
LazyMapTo('some/lazy/comp')(() => import('../test/lazy-component-wrapper/lazy.component').then((m) => m.LazyComponent));
MapTo<DirectiveComponent>('directive/comp')(DirectiveComponent);
LazyMapTo<LazyComponentType>('some/lazy/comp')(() => import('../test/lazy-component-wrapper/lazy.component').then((m) => m.LazyComponent));

describe('AEMComponentDirective', () => {

Expand Down
11 changes: 6 additions & 5 deletions src/lib/layout/aem-component.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ import {
OnDestroy,
OnInit,
Renderer2,
Type,
ViewContainerRef
} from '@angular/core';

import { ComponentMapping } from './component-mapping';
import { ComponentMapping, MappedComponentProperties } from './component-mapping';
import { Constants } from './constants';
import { Utils } from './utils';

Expand All @@ -52,7 +53,7 @@ export class AEMComponentDirective implements AfterViewInit, OnInit, OnDestroy,
/**
* Dynamically created component
*/
private _component: ComponentRef<any>;
private _component: ComponentRef<MappedComponentProperties>;
/**
* Model item that corresponds to the current component
*/
Expand Down Expand Up @@ -103,7 +104,7 @@ export class AEMComponentDirective implements AfterViewInit, OnInit, OnDestroy,
async ngOnInit() {

if (this.type) {
const mappedFn = ComponentMapping.get(this.type);
const mappedFn:Type<MappedComponentProperties> = ComponentMapping.get<MappedComponentProperties>(this.type);

if (mappedFn) {
this.renderComponent(mappedFn);
Expand All @@ -117,7 +118,7 @@ export class AEMComponentDirective implements AfterViewInit, OnInit, OnDestroy,
}

async initializeAsync() {
const lazyMappedPromise: Promise<unknown> = ComponentMapping.lazyGet(this.type);
const lazyMappedPromise: Promise<Type<MappedComponentProperties>> = ComponentMapping.lazyGet<MappedComponentProperties>(this.type);

try {
const LazyResolvedComponent = await lazyMappedPromise;
Expand Down Expand Up @@ -145,7 +146,7 @@ export class AEMComponentDirective implements AfterViewInit, OnInit, OnDestroy,
*
* @param componentDefinition The component definition to render
*/
private renderComponent(componentDefinition: any) {
private renderComponent(componentDefinition: Type<MappedComponentProperties>) {
if (componentDefinition) {
const factory = this.factoryResolver.resolveComponentFactory(componentDefinition);

Expand Down
41 changes: 26 additions & 15 deletions src/lib/layout/aem-container/aem-container.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import { Component, Input } from '@angular/core';
import { Constants } from '../constants';
import { Utils } from '../utils';
import { AbstractMappedComponent, ComponentMapping, MappedComponentProperties } from '../component-mapping';
import { Model } from "@adobe/aem-spa-page-model-manager";

/**
* @private
Expand All @@ -29,6 +31,25 @@ const PLACEHOLDER_ITEM_NAME = '*';
*/
const CONTAINER_CLASS_NAMES = 'aem-container';

/**
* Properties corresponding to the AEMContainerComponent
*/
export interface AEMContainerComponentProperties extends MappedComponentProperties {
componentMapping?: typeof ComponentMapping;
/**
* Map of model items included in the current container
*/
cqItems: { [key: string]: Model };
/**
* Array of model item keys
*/
cqItemsOrder: string[];
/**
* Class names of the current component
*/
classNames: string;
}

@Component({
selector: 'aem-container',
host: {
Expand All @@ -41,27 +62,17 @@ const CONTAINER_CLASS_NAMES = 'aem-container';
* The current component provides the base presentational logic common to containers such as a grid or a page.
* Container have in common the notion of item holders. Items are represented in the model by the fields _:items_ and _:itemsOrder_
*/
export class AEMContainerComponent {
/**
* Map of model items included in the current container
*/
export class AEMContainerComponent extends AbstractMappedComponent implements AEMContainerComponentProperties{

@Input() cqItems;
/**
* Array of model item keys
*/

@Input() cqItemsOrder;
/**
* Path to the model associated with the current instance of the component
*/
@Input() cqPath = '';

@Input() classNames;
/**
* Key of the model structure
*/
@Input() modelName = '';
/**
* Class names of the current component
*/
@Input() classNames: string;

/**
* Returns weather of not we are in the editor
Expand Down
49 changes: 31 additions & 18 deletions src/lib/layout/aem-responsivegrid/aem-responsivegrid.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@

import { Component, Input } from '@angular/core';
import { Constants } from '../constants';
import { AEMAllowedComponentsContainerComponent } from '../aem-allowed-components-container/aem-allowed-components-container.component';
import {
AEMAllowedComponentsContainerComponent,
AEMAllowedComponentsContainerComponentProperties
} from '../aem-allowed-components-container/aem-allowed-components-container.component';

/**
* @private
Expand All @@ -24,34 +27,44 @@ const PLACEHOLDER_CLASS_NAMES = 'aem-Grid-newComponent';
*/
const RESPONSIVE_GRID_TYPE = 'wcm/foundation/components/responsivegrid';

@Component({
selector: 'aem-responsivegrid',
host: {
'[class]': 'hostClasses',
'[attr.data-cq-data-path]': 'cqPath'
},
templateUrl: './aem-responsivegrid.component.html'
})
/**
* The current class carries the base presentational logic of the AEM Layout Container (aka. Responsive grid)
* Properties corresponding to the AEMResponsiveGridComponent.
* The AEMResponsiveGridComponent carries the base presentational logic of the AEM Layout Container.
*/
export class AEMResponsiveGridComponent extends AEMAllowedComponentsContainerComponent {
export interface AEMResponsiveGridComponentProperties extends AEMAllowedComponentsContainerComponentProperties {
/**
* Class names associated with the current responsive grid
*/
@Input() gridClassNames: string;
gridClassNames: string;
/**
* Map of class names corresponding to each child of the current responsive grid
*/
@Input() columnClassNames: any;
/**
* Class names of the current component
*/
@Input() classNames: string;
columnClassNames: { [key: string]: string };

/**
* Current number of columns of the grid
*/
@Input() columnCount: number;
columnCount: number;
}


@Component({
selector: 'aem-responsivegrid',
host: {
'[class]': 'hostClasses',
'[attr.data-cq-data-path]': 'cqPath'
},
templateUrl: './aem-responsivegrid.component.html'
})
/**
* The current class carries the base presentational logic of the AEM Layout Container (aka. Responsive grid)
*/
export class AEMResponsiveGridComponent extends AEMAllowedComponentsContainerComponent implements AEMResponsiveGridComponentProperties{

@Input() gridClassNames;
@Input() columnClassNames;
@Input() classNames;
@Input() columnCount;

/**
* Returns the column class names for a given column
Expand Down
Loading

0 comments on commit a2f2e6b

Please sign in to comment.