Skip to content

Commit

Permalink
fix(angular): 2-way data-binding for inlined Inputs (#533)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandertrefz authored Dec 6, 2024
1 parent be768be commit 61a3975
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { Components } from 'component-library';
inputs: ['buttonType', 'color', 'disabled', 'download', 'expand', 'fill', 'href', 'mode', 'rel', 'shape', 'size', 'strong', 'target', 'type'],
})
export class MyButton {
protected el: HTMLElement;
protected el: HTMLMyButtonElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand Down Expand Up @@ -50,7 +50,7 @@ export declare interface MyButton extends Components.MyButton {
inputs: ['checked', 'color', 'disabled', 'indeterminate', 'mode', 'name', 'value'],
})
export class MyCheckbox {
protected el: HTMLElement;
protected el: HTMLMyCheckboxElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand Down Expand Up @@ -88,7 +88,7 @@ export declare interface MyCheckbox extends Components.MyCheckbox {
inputs: ['age', 'favoriteKidName', 'first', 'kidsNames', 'last', 'middle'],
})
export class MyComponent {
protected el: HTMLElement;
protected el: HTMLMyComponentElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand Down Expand Up @@ -117,7 +117,7 @@ export declare interface MyComponent extends Components.MyComponent {
inputs: ['accept', 'autocapitalize', 'autocomplete', 'autocorrect', 'autofocus', 'clearInput', 'clearOnEdit', 'color', 'disabled', 'enterkeyhint', 'inputmode', 'max', 'maxlength', 'min', 'minlength', 'mode', 'multiple', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'size', 'spellcheck', 'step', 'type', 'value'],
})
export class MyInput {
protected el: HTMLElement;
protected el: HTMLMyInputElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand Down Expand Up @@ -160,7 +160,7 @@ export declare interface MyInput extends Components.MyInput {
inputs: ['animated', 'backdropDismiss', 'component', 'componentProps', 'cssClass', 'event', 'keyboardClose', 'mode', 'showBackdrop', 'translucent'],
})
export class MyPopover {
protected el: HTMLElement;
protected el: HTMLMyPopoverElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand Down Expand Up @@ -202,7 +202,7 @@ export declare interface MyPopover extends Components.MyPopover {
inputs: ['color', 'disabled', 'mode', 'name', 'value'],
})
export class MyRadio {
protected el: HTMLElement;
protected el: HTMLMyRadioElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand Down Expand Up @@ -238,7 +238,7 @@ export declare interface MyRadio extends Components.MyRadio {
inputs: ['allowEmptySelection', 'name', 'value'],
})
export class MyRadioGroup {
protected el: HTMLElement;
protected el: HTMLMyRadioGroupElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand Down Expand Up @@ -268,7 +268,7 @@ export declare interface MyRadioGroup extends Components.MyRadioGroup {
inputs: ['color', 'debounce', 'disabled', 'dualKnobs', 'max', 'min', 'mode', 'name', 'pin', 'snaps', 'step', 'ticks', 'value'],
})
export class MyRange {
protected el: HTMLElement;
protected el: HTMLMyRangeElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand Down
21 changes: 17 additions & 4 deletions packages/angular/src/generate-angular-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,29 @@ import type { OutputType } from './types';
*
* @param prop A ComponentCompilerEvent or ComponentCompilerProperty to turn into a property declaration.
* @param type The name of the type (e.g. 'string')
* @param inlinePropertyAsSetter Inlines the entire property as an empty Setter, to aid Angulars Compilerp
* @returns The property declaration as a string.
*/
function createPropertyDeclaration(prop: ComponentCompilerEvent | ComponentCompilerProperty, type: string): string {
function createPropertyDeclaration(
prop: ComponentCompilerEvent | ComponentCompilerProperty,
type: string,
inlinePropertyAsSetter: boolean = false
): string {
const comment = createDocComment(prop.docs);
let eventName = prop.name;
if (/[-/]/.test(prop.name)) {
// If a member name includes a dash or a forward slash, we need to wrap it in quotes.
// https://github.com/ionic-team/stencil-ds-output-targets/issues/212
eventName = `'${prop.name}'`;
}
return `${comment.length > 0 ? ` ${comment}` : ''}

if (inlinePropertyAsSetter) {
return `${comment.length > 0 ? ` ${comment}` : ''}
set ${eventName}(_: ${type}) {};`;
} else {
return `${comment.length > 0 ? ` ${comment}` : ''}
${eventName}: ${type};`;
}
}

/**
Expand Down Expand Up @@ -79,10 +90,12 @@ export const createAngularComponentDefinition = (
}

const propertyDeclarations = inlineComponentProps.map((m) =>
createPropertyDeclaration(m, `Components.${tagNameAsPascal}['${m.name}']`)
createPropertyDeclaration(m, `Components.${tagNameAsPascal}['${m.name}']`, true)
);

const propertiesDeclarationText = ['protected el: HTMLElement;', ...propertyDeclarations].join('\n ');
const propertiesDeclarationText = [`protected el: HTML${tagNameAsPascal}Element;`, ...propertyDeclarations].join(
'\n '
);

/**
* Notes on the generated output:
Expand Down
22 changes: 11 additions & 11 deletions packages/angular/tests/generate-angular-component.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('createAngularComponentDefinition()', () => {
inputs: [],
})
export class MyComponent {
protected el: HTMLElement;
protected el: HTMLMyComponentElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand All @@ -38,7 +38,7 @@ export class MyComponent {
inputs: ['my-input', 'my-other-input'],
})
export class MyComponent {
protected el: HTMLElement;
protected el: HTMLMyComponentElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand All @@ -65,7 +65,7 @@ export class MyComponent {
inputs: [],
})
export class MyComponent {
protected el: HTMLElement;
protected el: HTMLMyComponentElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand All @@ -88,7 +88,7 @@ export class MyComponent {
inputs: [],
})
export class MyComponent {
protected el: HTMLElement;
protected el: HTMLMyComponentElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand All @@ -112,7 +112,7 @@ export class MyComponent {
inputs: [],
})
export class MyComponent {
protected el: HTMLElement;
protected el: HTMLMyComponentElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand All @@ -135,7 +135,7 @@ export class MyComponent {
inputs: ['my-input', 'my-other-input'],
})
export class MyComponent {
protected el: HTMLElement;
protected el: HTMLMyComponentElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand All @@ -162,7 +162,7 @@ export class MyComponent {
inputs: [],
})
export class MyComponent {
protected el: HTMLElement;
protected el: HTMLMyComponentElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand All @@ -186,7 +186,7 @@ export class MyComponent {
inputs: [],
})
export class MyComponent {
protected el: HTMLElement;
protected el: HTMLMyComponentElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand All @@ -209,7 +209,7 @@ export class MyComponent {
standalone: true
})
export class MyComponent {
protected el: HTMLElement;
protected el: HTMLMyComponentElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand Down Expand Up @@ -241,11 +241,11 @@ export class MyComponent {
inputs: ['myMember'],
})
export class MyComponent {
protected el: HTMLElement;
protected el: HTMLMyComponentElement;
/**
* This is a jsDoc for myMember @deprecated use v2 of this API
*/
myMember: Components.MyComponent['myMember'];
set myMember(_: Components.MyComponent['myMember']) {};
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
Expand Down

0 comments on commit 61a3975

Please sign in to comment.