Skip to content

Commit

Permalink
Refactoring: extract default step templates to separate components to…
Browse files Browse the repository at this point in the history
… have properly typed "step" variables.
  • Loading branch information
hakimio committed Dec 30, 2024
1 parent 2387484 commit d9f7ec7
Show file tree
Hide file tree
Showing 36 changed files with 885 additions and 768 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
@let step = this.step();

<ion-card>
<ion-card-header>
<ion-card-title>{{step.title}}</ion-card-title>
<ion-button
class="close"
fill="clear"
shape="round"
(click)="tourService.end()"
>
<ion-icon slot="icon-only" name="close-outline"></ion-icon>
</ion-button>
</ion-card-header>

<ion-card-content
[innerHTML]="step.content"
></ion-card-content>

<div
class="footer"
[class.no-progress]="!step.showProgress"
>
<ion-button
fill="clear"
[disabled]="!tourService.hasPrev(step)"
(click)="tourService.prev()"
>
<ion-icon slot="start" name="chevron-back-outline"></ion-icon>
{{ step.prevBtnTitle }}
</ion-button>
@if (step.showProgress) {
<div class="progress">{{ tourService.steps.indexOf(step) + 1 }} / {{ tourService.steps.length }}</div>
}
@if (tourService.hasNext(step) && !step.nextOnAnchorClick) {
<ion-button
fill="clear"
(click)="tourService.next()"
>
{{ step.nextBtnTitle }}
<ion-icon slot="end" name="chevron-forward-outline"></ion-icon>
</ion-button>
}
@if (!tourService.hasNext(step)) {
<ion-button
fill="clear"
(click)="tourService.end()"
>
{{ step.endBtnTitle }}
</ion-button>
}
</div>
</ion-card>
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
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-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;

>* {
max-width: fit-content;

&:last-child {
justify-self: flex-end;
}
}

.progress {
font-size: 12px;
font-weight: 600;
color: rgba(0, 0, 0, .38);
white-space: nowrap;
}

&.no-progress {
grid-template-columns: 1fr 1fr;
}

ion-button {
text-transform: capitalize;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {ChangeDetectionStrategy, Component, inject, input} from '@angular/core';
import type {IonStepOption} from '../../step-option.interface';
import {IonTourService} from '../../ion-tour.service';
import {IonButton, IonCard, IonCardContent, IonCardHeader, IonCardTitle, IonIcon} from '@ionic/angular/standalone';
import {addIcons} from 'ionicons';
import {chevronBackOutline, chevronForwardOutline, closeOutline} from 'ionicons/icons';

@Component({
selector: 'tour-default-step-template',
imports: [
IonButton,
IonCard,
IonCardContent,
IonCardHeader,
IonCardTitle,
IonIcon
],
templateUrl: './tour-default-step-template.component.html',
styleUrl: './tour-default-step-template.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class TourDefaultStepTemplateComponent {

readonly step = input.required<IonStepOption>();
protected readonly tourService = inject(IonTourService);

constructor() {
this.addIonicIcons();
}

private addIonicIcons() {
addIcons({
closeOutline,
chevronBackOutline,
chevronForwardOutline
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,55 +21,7 @@
</ion-popover>

<ng-template #defaultTemplate let-step="step">
<ion-card>
<ion-card-header>
<ion-card-title>{{step.title}}</ion-card-title>
<ion-button
class="close"
fill="clear"
shape="round"
(click)="tourService.end()"
>
<ion-icon slot="icon-only" name="close-outline"></ion-icon>
</ion-button>
</ion-card-header>

<ion-card-content
[innerHTML]="step.content"
></ion-card-content>

<div
class="footer"
[class.no-progress]="!step.showProgress"
>
<ion-button
fill="clear"
[disabled]="!tourService.hasPrev(step)"
(click)="tourService.prev()"
>
<ion-icon slot="start" name="chevron-back-outline"></ion-icon>
{{ step.prevBtnTitle }}
</ion-button>
@if (step.showProgress) {
<div class="progress">{{ tourService.steps.indexOf(step) + 1 }} / {{ tourService.steps.length }}</div>
}
@if (tourService.hasNext(step) && !step.nextOnAnchorClick) {
<ion-button
fill="clear"
(click)="tourService.next()"
>
{{ step.nextBtnTitle }}
<ion-icon slot="end" name="chevron-forward-outline"></ion-icon>
</ion-button>
}
@if (!tourService.hasNext(step)) {
<ion-button
fill="clear"
(click)="tourService.end()"
>
{{ step.endBtnTitle }}
</ion-button>
}
</div>
</ion-card>
<tour-default-step-template
[step]="step"
/>
</ng-template>
Original file line number Diff line number Diff line change
@@ -1,61 +1,3 @@
ion-popover {
pointer-events: none;
}

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-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;

>* {
max-width: fit-content;

&:last-child {
justify-self: flex-end;
}
}

.progress {
font-size: 12px;
font-weight: 600;
color: rgba(0, 0, 0, .38);
white-space: nowrap;
}

&.no-progress {
grid-template-columns: 1fr 1fr;
}

ion-button {
text-transform: capitalize;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,12 @@ import {
ViewChild
} from '@angular/core';
import {TourHotkeyListenerComponent} from 'ngx-ui-tour-core';
import {
createAnimation,
IonButton,
IonCard,
IonCardContent,
IonCardHeader,
IonCardTitle,
IonIcon,
IonPopover
} from '@ionic/angular/standalone';
import {createAnimation, IonPopover} from '@ionic/angular/standalone';
import {NgTemplateOutlet} from '@angular/common';
import type {IonStepOption} from '../step-option.interface';
import {TourStepTemplateService} from '../tour-step-template.service';
import {IonTourService} from '../ion-tour.service';
import {addIcons} from 'ionicons';
import {chevronBackOutline, chevronForwardOutline, closeOutline} from 'ionicons/icons';
import {TourDefaultStepTemplateComponent} from './tour-default-step-template/tour-default-step-template.component';

@Component({
selector: 'tour-step-template',
Expand All @@ -33,12 +23,7 @@ import {chevronBackOutline, chevronForwardOutline, closeOutline} from 'ionicons/
imports: [
NgTemplateOutlet,
IonPopover,
IonCard,
IonCardHeader,
IonCardTitle,
IonButton,
IonIcon,
IonCardContent
TourDefaultStepTemplateComponent
],
changeDetection: ChangeDetectionStrategy.OnPush
})
Expand All @@ -59,21 +44,8 @@ export class TourStepTemplateComponent extends TourHotkeyListenerComponent imple
protected override readonly tourService = inject(IonTourService);
private readonly tourStepTemplateService = inject(TourStepTemplateService);

constructor() {
super();
this.addIonicIcons();
}

private addIonicIcons() {
addIcons({
closeOutline,
chevronBackOutline,
chevronForwardOutline
});
}

public ngAfterViewInit() {
this.tourStepTemplateService.templateComponent = this;
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
@let step = this.step();

<mat-card
(click)="$event.stopPropagation()"
[style.width]="step.stepDimensions?.width"
[style.min-width]="step.stepDimensions?.minWidth"
[style.max-width]="step.stepDimensions?.maxWidth"
>
<mat-card-header>
<div class="header-group">
<mat-card-title>
{{ step.title }}
</mat-card-title>
<button
mat-icon-button
(click)="tourService.end()"
class="close"
>
<mat-icon>close</mat-icon>
</button>
</div>
</mat-card-header>

<mat-card-content
class="mat-body"
[innerHTML]="step.content"
></mat-card-content>

<mat-card-actions
[class.no-progress]="!step.showProgress"
>
<button
mat-button
class="prev"
[disabled]="!tourService.hasPrev(step)"
(click)="tourService.prev()"
>
<mat-icon>chevron_left</mat-icon>
{{ step.prevBtnTitle }}
</button>
@if (step.showProgress) {
<div class="progress">{{ tourService.steps.indexOf(step) + 1 }} / {{ tourService.steps.length }}</div>
}
@if (tourService.hasNext(step) && !step.nextOnAnchorClick) {
<button
class="next"
(click)="tourService.next()"
mat-button
>
{{ step.nextBtnTitle }}
<mat-icon iconPositionEnd>chevron_right</mat-icon>
</button>
}
@if (!tourService.hasNext(step)) {
<button
mat-button
(click)="tourService.end()"
>
{{ step.endBtnTitle }}
</button>
}
</mat-card-actions>
</mat-card>
Loading

0 comments on commit d9f7ec7

Please sign in to comment.