UNPKG

ngx-ui-tour-ionic

Version:
211 lines (201 loc) 20.5 kB
import * as i0 from '@angular/core'; import { Injectable, inject, input, Component, ChangeDetectionStrategy, signal, TemplateRef, ViewChild, Input, ContentChild, ElementRef, Directive, NgModule } from '@angular/core'; import { TourService, TourHotkeyListenerComponent, BaseTourProxyAnchor } from 'ngx-ui-tour-core'; import { Config, IonButton, IonCard, IonCardContent, IonCardHeader, IonCardTitle, IonIcon, createAnimation, IonPopover } from '@ionic/angular/standalone'; import { DOCUMENT, NgTemplateOutlet } from '@angular/common'; import { addIcons } from 'ionicons'; import { closeOutline, chevronBackOutline, chevronForwardOutline } from 'ionicons/icons'; import { firstValueFrom } from 'rxjs'; class TourStepTemplateService { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TourStepTemplateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TourStepTemplateService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TourStepTemplateService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); class IonTourService extends TourService { constructor() { super(...arguments); this.config = inject(Config); this.document = inject(DOCUMENT); } initialize(steps, stepDefaults) { const userDefaults = this.getDefaults(), isIOS = this.config.get('mode') === 'ios'; stepDefaults ??= {}; stepDefaults.backdropConfig ??= userDefaults?.backdropConfig ?? {}; stepDefaults.backdropConfig.parentContainer ??= userDefaults?.backdropConfig?.parentContainer ?? 'ion-app'; stepDefaults.delayAfterNavigation ??= userDefaults?.delayAfterNavigation ?? (isIOS ? 700 : 500); stepDefaults.trapFocus ??= userDefaults?.trapFocus ?? false; super.initialize(steps, stepDefaults); } // noinspection JSUnusedGlobalSymbols showStep(step) { // In case "scrollContainer" is already set to HTMLElement, we DO want to set it again since the current // html element reference might be already removed from DOM if (step.smoothScroll && (!step.scrollContainer || typeof step.scrollContainer !== 'string')) { const docEl = this.document.documentElement, tabsRouter = docEl.querySelector('ion-router-outlet[tabs=true]'), generalRouter = docEl.querySelector('ion-router-outlet'), router = tabsRouter ?? generalRouter, ionContent = router ? router.querySelector(':scope > .ion-page:not(.ion-page-hidden) ion-content') : docEl.querySelector('ion-content'); step.scrollContainer = ionContent?.shadowRoot.querySelector('[part=scroll]'); } return super.showStep(step); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: IonTourService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: IonTourService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: IonTourService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); class TourDefaultStepTemplateComponent { constructor() { this.step = input.required(); this.tourService = inject(IonTourService); this.addIonicIcons(); } addIonicIcons() { addIcons({ closeOutline, chevronBackOutline, chevronForwardOutline }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TourDefaultStepTemplateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: TourDefaultStepTemplateComponent, isStandalone: true, selector: "tour-default-step-template", inputs: { step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@let step = this.step();\r\n\r\n<ion-card>\r\n <ion-card-header>\r\n <ion-card-title>{{step.title}}</ion-card-title>\r\n <ion-button\r\n class=\"close\"\r\n fill=\"clear\"\r\n shape=\"round\"\r\n (click)=\"tourService.end()\"\r\n >\r\n <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>\r\n </ion-button>\r\n </ion-card-header>\r\n\r\n <ion-card-content\r\n [innerHTML]=\"step.content\"\r\n ></ion-card-content>\r\n\r\n <div\r\n class=\"footer\"\r\n [class.no-progress]=\"!step.showProgress\"\r\n >\r\n <ion-button\r\n fill=\"clear\"\r\n [disabled]=\"!tourService.hasPrev(step)\"\r\n (click)=\"tourService.prev()\"\r\n >\r\n <ion-icon slot=\"start\" name=\"chevron-back-outline\"></ion-icon>\r\n {{ step.prevBtnTitle }}\r\n </ion-button>\r\n @if (step.showProgress) {\r\n <div class=\"progress\">{{ tourService.steps.indexOf(step) + 1 }} / {{ tourService.steps.length }}</div>\r\n }\r\n @if (tourService.hasNext(step) && !step.nextOnAnchorClick) {\r\n <ion-button\r\n fill=\"clear\"\r\n (click)=\"tourService.next()\"\r\n >\r\n {{ step.nextBtnTitle }}\r\n <ion-icon slot=\"end\" name=\"chevron-forward-outline\"></ion-icon>\r\n </ion-button>\r\n }\r\n @if (!tourService.hasNext(step)) {\r\n <ion-button\r\n fill=\"clear\"\r\n (click)=\"tourService.end()\"\r\n >\r\n {{ step.endBtnTitle }}\r\n </ion-button>\r\n }\r\n </div>\r\n</ion-card>\r\n", styles: ["ion-card{margin:0;pointer-events:auto}ion-card-header{display:flex;flex-direction:row;align-items:center;justify-content:space-between;padding:8px 16px}ion-card-header ion-card-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}ion-button.close{--padding-start: 5px;--padding-end: 5px;--padding-top: 5px;--padding-bottom: 5px;margin:0 -8px 0 0}.footer{display:grid;grid-template-columns:1fr auto 1fr;padding:0 8px 8px;align-items:center;gap:8px}.footer>*{max-width:fit-content}.footer>*:last-child{justify-self:flex-end}.footer .progress{font-size:12px;font-weight:600;color:#00000061;white-space:nowrap}.footer.no-progress{grid-template-columns:1fr 1fr}.footer ion-button{text-transform:capitalize}\n"], dependencies: [{ kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TourDefaultStepTemplateComponent, decorators: [{ type: Component, args: [{ selector: 'tour-default-step-template', imports: [ IonButton, IonCard, IonCardContent, IonCardHeader, IonCardTitle, IonIcon ], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let step = this.step();\r\n\r\n<ion-card>\r\n <ion-card-header>\r\n <ion-card-title>{{step.title}}</ion-card-title>\r\n <ion-button\r\n class=\"close\"\r\n fill=\"clear\"\r\n shape=\"round\"\r\n (click)=\"tourService.end()\"\r\n >\r\n <ion-icon slot=\"icon-only\" name=\"close-outline\"></ion-icon>\r\n </ion-button>\r\n </ion-card-header>\r\n\r\n <ion-card-content\r\n [innerHTML]=\"step.content\"\r\n ></ion-card-content>\r\n\r\n <div\r\n class=\"footer\"\r\n [class.no-progress]=\"!step.showProgress\"\r\n >\r\n <ion-button\r\n fill=\"clear\"\r\n [disabled]=\"!tourService.hasPrev(step)\"\r\n (click)=\"tourService.prev()\"\r\n >\r\n <ion-icon slot=\"start\" name=\"chevron-back-outline\"></ion-icon>\r\n {{ step.prevBtnTitle }}\r\n </ion-button>\r\n @if (step.showProgress) {\r\n <div class=\"progress\">{{ tourService.steps.indexOf(step) + 1 }} / {{ tourService.steps.length }}</div>\r\n }\r\n @if (tourService.hasNext(step) && !step.nextOnAnchorClick) {\r\n <ion-button\r\n fill=\"clear\"\r\n (click)=\"tourService.next()\"\r\n >\r\n {{ step.nextBtnTitle }}\r\n <ion-icon slot=\"end\" name=\"chevron-forward-outline\"></ion-icon>\r\n </ion-button>\r\n }\r\n @if (!tourService.hasNext(step)) {\r\n <ion-button\r\n fill=\"clear\"\r\n (click)=\"tourService.end()\"\r\n >\r\n {{ step.endBtnTitle }}\r\n </ion-button>\r\n }\r\n </div>\r\n</ion-card>\r\n", styles: ["ion-card{margin:0;pointer-events:auto}ion-card-header{display:flex;flex-direction:row;align-items:center;justify-content:space-between;padding:8px 16px}ion-card-header ion-card-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}ion-button.close{--padding-start: 5px;--padding-end: 5px;--padding-top: 5px;--padding-bottom: 5px;margin:0 -8px 0 0}.footer{display:grid;grid-template-columns:1fr auto 1fr;padding:0 8px 8px;align-items:center;gap:8px}.footer>*{max-width:fit-content}.footer>*:last-child{justify-self:flex-end}.footer .progress{font-size:12px;font-weight:600;color:#00000061;white-space:nowrap}.footer.no-progress{grid-template-columns:1fr 1fr}.footer ion-button{text-transform:capitalize}\n"] }] }], ctorParameters: () => [] }); class TourStepTemplateComponent extends TourHotkeyListenerComponent { constructor() { super(...arguments); this.step = signal({}); this.noopLeaveAnimation = () => createAnimation(); this.tourService = inject(IonTourService); this.tourStepTemplateService = inject(TourStepTemplateService); } ngAfterViewInit() { this.tourStepTemplateService.templateComponent = this; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TourStepTemplateComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: TourStepTemplateComponent, isStandalone: true, selector: "tour-step-template", inputs: { stepTemplate: "stepTemplate" }, queries: [{ propertyName: "stepTemplateContent", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "ionPopover", first: true, predicate: IonPopover, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "@let step = this.step();\r\n\r\n<ion-popover\r\n [leaveAnimation]=\"noopLeaveAnimation\"\r\n [backdropDismiss]=\"false\"\r\n [keyboardClose]=\"false\"\r\n [showBackdrop]=\"false\"\r\n [dismissOnSelect]=\"false\"\r\n [style.--min-width]=\"step?.stepDimensions?.minWidth\"\r\n [style.--max-width]=\"step?.stepDimensions?.maxWidth\"\r\n [style.--width]=\"step?.stepDimensions?.width\"\r\n [arrow]=\"step?.showArrow ?? true\"\r\n [focusTrap]=\"step?.trapFocus ?? false\"\r\n>\r\n <ng-template>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n stepTemplate || stepTemplateContent || defaultTemplate;\r\n context: {step: step}\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n</ion-popover>\r\n\r\n<ng-template #defaultTemplate let-step=\"step\">\r\n <tour-default-step-template\r\n [step]=\"step\"\r\n />\r\n</ng-template>\r\n", styles: ["ion-popover{pointer-events:none}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IonPopover, selector: "ion-popover" }, { kind: "component", type: TourDefaultStepTemplateComponent, selector: "tour-default-step-template", inputs: ["step"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TourStepTemplateComponent, decorators: [{ type: Component, args: [{ selector: 'tour-step-template', imports: [ NgTemplateOutlet, IonPopover, TourDefaultStepTemplateComponent ], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let step = this.step();\r\n\r\n<ion-popover\r\n [leaveAnimation]=\"noopLeaveAnimation\"\r\n [backdropDismiss]=\"false\"\r\n [keyboardClose]=\"false\"\r\n [showBackdrop]=\"false\"\r\n [dismissOnSelect]=\"false\"\r\n [style.--min-width]=\"step?.stepDimensions?.minWidth\"\r\n [style.--max-width]=\"step?.stepDimensions?.maxWidth\"\r\n [style.--width]=\"step?.stepDimensions?.width\"\r\n [arrow]=\"step?.showArrow ?? true\"\r\n [focusTrap]=\"step?.trapFocus ?? false\"\r\n>\r\n <ng-template>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n stepTemplate || stepTemplateContent || defaultTemplate;\r\n context: {step: step}\r\n \"\r\n ></ng-container>\r\n </ng-template>\r\n</ion-popover>\r\n\r\n<ng-template #defaultTemplate let-step=\"step\">\r\n <tour-default-step-template\r\n [step]=\"step\"\r\n />\r\n</ng-template>\r\n", styles: ["ion-popover{pointer-events:none}\n"] }] }], propDecorators: { ionPopover: [{ type: ViewChild, args: [IonPopover, { static: true }] }], stepTemplate: [{ type: Input }], stepTemplateContent: [{ type: ContentChild, args: [TemplateRef] }] } }); class TourAnchorIonPopoverDirective { constructor() { this.isActive = signal(false); this.element = inject(ElementRef); this.tourService = inject(IonTourService); this.stepTemplateService = inject(TourStepTemplateService); } ngOnInit() { this.tourService.register(this.tourAnchor, this); } ngOnDestroy() { this.tourService.unregister(this.tourAnchor); } async showTourStep(step) { const templateComponent = this.stepTemplateService.templateComponent, popover = templateComponent.ionPopover; if (popover.isCmpOpen) { await firstValueFrom(popover.didDismiss); } this.isActive.set(true); templateComponent.step.set(step); popover.alignment = step.placement?.alignment; popover.side = step.placement?.side ?? 'bottom'; popover.cssClass = step.popoverClass; const event = { target: this.element.nativeElement }; await popover.present(event); } hideTourStep() { this.isActive.set(false); const popover = this.stepTemplateService.templateComponent.ionPopover; popover.dismiss(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TourAnchorIonPopoverDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.5", type: TourAnchorIonPopoverDirective, isStandalone: true, selector: "[tourAnchor]", inputs: { tourAnchor: "tourAnchor" }, host: { properties: { "class.touranchor--is-active": "isActive()" } }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TourAnchorIonPopoverDirective, decorators: [{ type: Directive, args: [{ selector: '[tourAnchor]', host: { '[class.touranchor--is-active]': 'isActive()' } }] }], propDecorators: { tourAnchor: [{ type: Input }] } }); class TourProxyAnchorComponent extends BaseTourProxyAnchor { constructor() { super(...arguments); // noinspection JSUnusedGlobalSymbols this.anchorDirective = inject(TourAnchorIonPopoverDirective, { host: true }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TourProxyAnchorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: TourProxyAnchorComponent, isStandalone: true, selector: "tour-proxy-anchor", inputs: { anchorEl: "anchorEl" }, usesInheritance: true, hostDirectives: [{ directive: TourAnchorIonPopoverDirective, inputs: ["tourAnchor", "anchorId"] }], ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TourProxyAnchorComponent, decorators: [{ type: Component, args: [{ selector: 'tour-proxy-anchor', template: ``, changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [{ directive: TourAnchorIonPopoverDirective, inputs: ['tourAnchor: anchorId'] }] }] }], propDecorators: { anchorEl: [{ type: Input, args: [{ required: true }] }] } }); const COMPONENTS = [TourStepTemplateComponent, TourAnchorIonPopoverDirective, TourProxyAnchorComponent]; class TourIonPopoverModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TourIonPopoverModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.5", ngImport: i0, type: TourIonPopoverModule, imports: [TourStepTemplateComponent, TourAnchorIonPopoverDirective, TourProxyAnchorComponent], exports: [TourStepTemplateComponent, TourAnchorIonPopoverDirective, TourProxyAnchorComponent] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TourIonPopoverModule, imports: [TourStepTemplateComponent] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: TourIonPopoverModule, decorators: [{ type: NgModule, args: [{ imports: COMPONENTS, exports: COMPONENTS }] }] }); /** * Generated bundle index. Do not edit. */ export { TourAnchorIonPopoverDirective, TourIonPopoverModule, TourProxyAnchorComponent, IonTourService as TourService, TourStepTemplateComponent }; //# sourceMappingURL=ngx-ui-tour-ionic.mjs.map