Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/modal/base-modal.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import {
@Directive({
selector: "[cdsBaseModal], [ibmBaseModal]"
})
export class BaseModal {
export class BaseModal<R = any> {
/**
* Base event emitter to propagate close events
*/
@Output() close = new EventEmitter();
@Output() close = new EventEmitter<R>();

/**
* Controls the open state of the modal
Expand All @@ -27,7 +27,7 @@ export class BaseModal {
/**
* Default method to handle closing the modal
*/
closeModal(): void {
this.close.emit();
closeModal(value?: R): void {
this.close.emit(value);
}
}
7 changes: 5 additions & 2 deletions src/modal/base-modal.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import {
Injector,
Injectable,
inject,
EnvironmentInjector
EnvironmentInjector,
Type
} from "@angular/core";
import { PlaceholderService } from "carbon-components-angular/placeholder";
import { tap, delay } from "rxjs/operators";
import {BaseModal} from "./base-modal.class";


/**
Expand Down Expand Up @@ -44,7 +46,8 @@ export class BaseModalService {
* Creates and renders the modal component that is passed in.
* `inputs` is an optional parameter of `data` that can be passed to the `Modal` component.
*/
create<T>(data: { component: any, inputs?: any }): ComponentRef<any> {
create<T extends BaseModal, I extends Record<any, unknown> = Record<string, unknown>>(
data: { component: Type<T>, inputs?: I }): ComponentRef<T> {
let defaults = { inputs: {} };
data = Object.assign({}, defaults, data);

Expand Down
18 changes: 10 additions & 8 deletions src/modal/stories/data-passing.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,33 @@ import { InputModal } from "./input-modal.component";
selector: "app-data-passing-modal",
template: `
<button class="cds--btn cds--btn--primary" (click)="openModal()">Open Modal</button>
<h3>Data passed from input modal on input change: </h3>{{ modalInputValue }}
<h3>Data passed from input modal on close: </h3>{{ modalInputValue }}
`
})
export class DataPassingModal implements AfterContentInit {
export class DataPassingModal {
@Input() modalText = "Hello, World";
@Input() size = "md";

protected modalInputValue = "";
protected data: Observable<string> = new Subject<string>();

constructor(protected modalService: ModalService) { }

openModal() {
this.modalService.create({
const componentRef = this.modalService.create({
component: InputModal,
inputs: {
modalText: this.modalText,
inputValue: this.modalInputValue,
size: this.size,
data: this.data
}
});
}

ngAfterContentInit() {
this.data.subscribe(value => this.modalInputValue = value);
componentRef.instance.close.subscribe((result: string) => {
if (result === undefined) {
console.log("Modal closed without value");
} else {
this.modalInputValue = result;
}
});
}
}
10 changes: 6 additions & 4 deletions src/modal/stories/input-modal.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,24 @@ import { ModalService, BaseModal } from "../";
</section>
<cds-modal-footer>
<button class="cds--btn cds--btn--secondary" (click)="closeModal()">Cancel</button>
<button class="cds--btn cds--btn--primary" modal-primary-focus (click)="closeModal()">Save</button>
<button class="cds--btn cds--btn--primary" modal-primary-focus (click)="closeModal(outputValue)">Save</button>
</cds-modal-footer>
</cds-modal>
`
})
export class InputModal extends BaseModal {
export class InputModal extends BaseModal<string> {

protected outputValue = this.inputValue;

constructor(
@Inject("modalText") public modalText,
@Inject("size") public size,
@Inject("data") public data,
@Inject("inputValue") public inputValue,
protected modalService: ModalService) {
super();
}

onChange(event) {
this.data.next(event.target.value);
this.outputValue = event.target.value;
}
}
13 changes: 7 additions & 6 deletions src/placeholder/placeholder.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import {
ViewContainerRef,
Injector,
EnvironmentInjector,
inject
inject,
Type
} from "@angular/core";
import { Injectable } from "@angular/core";

Expand Down Expand Up @@ -35,24 +36,24 @@ export class PlaceholderService {
/**
* Creates and returns component in the view.
*/
createComponent(
component: ComponentRef<any>,
createComponent<T>(
component: Type<T>,
injector: Injector,
id?: any,
environment: EnvironmentInjector = undefined
): ComponentRef<any> {
): ComponentRef<T> {
if (id) {
if (!this.viewContainerMap.has(id)) {
console.error(`No view container with id ${id} found`);
return;
}
return this.viewContainerMap.get(id).createComponent(component as any, { index: this.viewContainerMap.size, injector });
return this.viewContainerMap.get(id).createComponent(component, { index: this.viewContainerMap.size, injector });
}
if (!this.viewContainerRef) {
console.error("No view container defined! Likely due to a missing `cds-placeholder`");
return;
}
return this.viewContainerRef.createComponent(component as any,
return this.viewContainerRef.createComponent(component,
{
index: this.viewContainerRef.length,
injector,
Expand Down