diff --git a/packages/angular/common/ng-package.json b/packages/angular/common/ng-package.json new file mode 100644 index 0000000000..b15651d6c2 --- /dev/null +++ b/packages/angular/common/ng-package.json @@ -0,0 +1,5 @@ +{ + "lib": { + "entryFile": "src/index.ts" + }, +} diff --git a/packages/angular/common/src/index.ts b/packages/angular/common/src/index.ts new file mode 100644 index 0000000000..623c26a199 --- /dev/null +++ b/packages/angular/common/src/index.ts @@ -0,0 +1,2 @@ +export { IonPopover } from './overlays/popover'; +export * from './utils'; diff --git a/packages/angular/common/src/overlays/popover.ts b/packages/angular/common/src/overlays/popover.ts new file mode 100644 index 0000000000..72427cc7f0 --- /dev/null +++ b/packages/angular/common/src/overlays/popover.ts @@ -0,0 +1,80 @@ +/* eslint-disable */ +/* tslint:disable */ +import { + ChangeDetectorRef, + Component, + ContentChild, + ElementRef, + EventEmitter, + NgZone, + TemplateRef, +} from '@angular/core'; +import { proxyOutputs } from '../utils'; +import { Components } from '@ionic/core'; +export declare interface IonPopover extends Components.IonPopover { + /** + * Emitted after the popover has presented. + */ + ionPopoverDidPresent: EventEmitter; + /** + * Emitted before the popover has presented. + */ + ionPopoverWillPresent: EventEmitter; + /** + * Emitted after the popover has dismissed. + */ + ionPopoverWillDismiss: EventEmitter; + /** + * Emitted after the popover has dismissed. + */ + ionPopoverDidDismiss: EventEmitter; + /** + * Emitted after the popover has presented. Shorthand for ionPopoverWillDismiss. + */ + didPresent: EventEmitter; + /** + * Emitted before the popover has presented. Shorthand for ionPopoverWillPresent. + */ + willPresent: EventEmitter; + /** + * Emitted after the popover has presented. Shorthand for ionPopoverWillDismiss. + */ + willDismiss: EventEmitter; + /** + * Emitted after the popover has dismissed. Shorthand for ionPopoverDidDismiss. + */ + didDismiss: EventEmitter; +} + +@Component({ template: '' }) +export class IonPopover { + // TODO(FW-2827): type + @ContentChild(TemplateRef, { static: false }) template: TemplateRef; + + isCmpOpen: boolean = false; + + protected el: HTMLElement; + + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + this.el = r.nativeElement; + + this.el.addEventListener('ionMount', () => { + this.isCmpOpen = true; + c.detectChanges(); + }); + this.el.addEventListener('didDismiss', () => { + this.isCmpOpen = false; + c.detectChanges(); + }); + proxyOutputs(this, this.el, [ + 'ionPopoverDidPresent', + 'ionPopoverWillPresent', + 'ionPopoverWillDismiss', + 'ionPopoverDidDismiss', + 'didPresent', + 'willPresent', + 'willDismiss', + 'didDismiss', + ]); + } +} diff --git a/packages/angular/common/src/utils/index.ts b/packages/angular/common/src/utils/index.ts new file mode 100644 index 0000000000..58ed93b7d3 --- /dev/null +++ b/packages/angular/common/src/utils/index.ts @@ -0,0 +1,57 @@ +/* eslint-disable */ +/* tslint:disable */ +import { fromEvent } from 'rxjs'; + +export const proxyInputs = (Cmp: any, inputs: string[]) => { + const Prototype = Cmp.prototype; + inputs.forEach((item) => { + Object.defineProperty(Prototype, item, { + get() { + return this.el[item]; + }, + set(val: any) { + this.z.runOutsideAngular(() => (this.el[item] = val)); + }, + }); + }); +}; + +export const proxyMethods = (Cmp: any, methods: string[]) => { + const Prototype = Cmp.prototype; + methods.forEach((methodName) => { + Prototype[methodName] = function () { + const args = arguments; + return this.z.runOutsideAngular(() => this.el[methodName].apply(this.el, args)); + }; + }); +}; + +export const proxyOutputs = (instance: any, el: any, events: string[]) => { + events.forEach((eventName) => (instance[eventName] = fromEvent(el, eventName))); +}; + +export const defineCustomElement = (tagName: string, customElement: any) => { + if (customElement !== undefined && typeof customElements !== 'undefined' && !customElements.get(tagName)) { + customElements.define(tagName, customElement); + } +}; + +// tslint:disable-next-line: only-arrow-functions +export function ProxyCmp(opts: { defineCustomElementFn?: () => void; inputs?: any; methods?: any }) { + const decorator = function (cls: any) { + const { defineCustomElementFn, inputs, methods } = opts; + + if (defineCustomElementFn !== undefined) { + defineCustomElementFn(); + } + + if (inputs) { + proxyInputs(cls, inputs); + } + if (methods) { + proxyMethods(cls, methods); + } + return cls; + }; + return decorator; +} diff --git a/packages/angular/src/directives/overlays/popover.ts b/packages/angular/src/directives/overlays/popover.ts index a1c1b37239..4fd1e884e6 100644 --- a/packages/angular/src/directives/overlays/popover.ts +++ b/packages/angular/src/directives/overlays/popover.ts @@ -1,51 +1,8 @@ /* eslint-disable */ /* tslint:disable */ -import { - ChangeDetectionStrategy, - ChangeDetectorRef, - Component, - ContentChild, - ElementRef, - EventEmitter, - NgZone, - TemplateRef, -} from '@angular/core'; -import { ProxyCmp, proxyOutputs } from '../angular-component-lib/utils'; -import { Components } from '@ionic/core'; -export declare interface IonPopover extends Components.IonPopover { - /** - * Emitted after the popover has presented. - */ - ionPopoverDidPresent: EventEmitter; - /** - * Emitted before the popover has presented. - */ - ionPopoverWillPresent: EventEmitter; - /** - * Emitted after the popover has dismissed. - */ - ionPopoverWillDismiss: EventEmitter; - /** - * Emitted after the popover has dismissed. - */ - ionPopoverDidDismiss: EventEmitter; - /** - * Emitted after the popover has presented. Shorthand for ionPopoverWillDismiss. - */ - didPresent: EventEmitter; - /** - * Emitted before the popover has presented. Shorthand for ionPopoverWillPresent. - */ - willPresent: EventEmitter; - /** - * Emitted after the popover has presented. Shorthand for ionPopoverWillDismiss. - */ - willDismiss: EventEmitter; - /** - * Emitted after the popover has dismissed. Shorthand for ionPopoverDidDismiss. - */ - didDismiss: EventEmitter; -} +import { IonPopover as IonPopoverBase, ProxyCmp } from '@ionic/angular/common'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; + @ProxyCmp({ inputs: [ 'alignment', @@ -98,34 +55,4 @@ export declare interface IonPopover extends Components.IonPopover { 'side', ], }) -export class IonPopover { - // TODO(FW-2827): type - @ContentChild(TemplateRef, { static: false }) template: TemplateRef; - - isCmpOpen: boolean = false; - - protected el: HTMLElement; - - constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { - this.el = r.nativeElement; - - this.el.addEventListener('ionMount', () => { - this.isCmpOpen = true; - c.detectChanges(); - }); - this.el.addEventListener('didDismiss', () => { - this.isCmpOpen = false; - c.detectChanges(); - }); - proxyOutputs(this, this.el, [ - 'ionPopoverDidPresent', - 'ionPopoverWillPresent', - 'ionPopoverWillDismiss', - 'ionPopoverDidDismiss', - 'didPresent', - 'willPresent', - 'willDismiss', - 'didDismiss', - ]); - } -} +export class IonPopover extends IonPopoverBase {} diff --git a/packages/angular/standalone/ng-package.json b/packages/angular/standalone/ng-package.json new file mode 100644 index 0000000000..b15651d6c2 --- /dev/null +++ b/packages/angular/standalone/ng-package.json @@ -0,0 +1,5 @@ +{ + "lib": { + "entryFile": "src/index.ts" + }, +} diff --git a/packages/angular/standalone/src/index.ts b/packages/angular/standalone/src/index.ts new file mode 100644 index 0000000000..73bb99afcb --- /dev/null +++ b/packages/angular/standalone/src/index.ts @@ -0,0 +1 @@ +export { IonPopover } from './overlays/popover'; diff --git a/packages/angular/standalone/src/overlays/popover.ts b/packages/angular/standalone/src/overlays/popover.ts new file mode 100644 index 0000000000..b266310371 --- /dev/null +++ b/packages/angular/standalone/src/overlays/popover.ts @@ -0,0 +1,61 @@ +/* eslint-disable */ +/* tslint:disable */ +import { IonPopover as IonPopoverBase, ProxyCmp } from '@ionic/angular/common'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +@ProxyCmp({ + inputs: [ + 'alignment', + 'animated', + 'arrow', + 'keepContentsMounted', + 'backdropDismiss', + 'cssClass', + 'dismissOnSelect', + 'enterAnimation', + 'event', + 'isOpen', + 'keyboardClose', + 'leaveAnimation', + 'mode', + 'showBackdrop', + 'translucent', + 'trigger', + 'triggerAction', + 'reference', + 'size', + 'side', + ], + methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss'], +}) +@Component({ + selector: 'ion-popover', + changeDetection: ChangeDetectionStrategy.OnPush, + template: ``, + inputs: [ + 'alignment', + 'animated', + 'arrow', + 'keepContentsMounted', + 'backdropDismiss', + 'cssClass', + 'dismissOnSelect', + 'enterAnimation', + 'event', + 'isOpen', + 'keyboardClose', + 'leaveAnimation', + 'mode', + 'showBackdrop', + 'translucent', + 'trigger', + 'triggerAction', + 'reference', + 'size', + 'side', + ], + standalone: true, + imports: [CommonModule] +}) +export class IonPopover extends IonPopoverBase {}