Skip to content

Commit e4d8aef

Browse files
Update to Shepherd 14.x (#2606)
* Update to Shepherd 14.x * Fix TS and tests
1 parent b469d33 commit e4d8aef

File tree

13 files changed

+136
-102
lines changed

13 files changed

+136
-102
lines changed

.prettierrc.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"use strict";
2+
3+
module.exports = {
4+
arrowParens: "always",
5+
proseWrap: "always",
6+
trailingComma: "none",
7+
singleQuote: true,
8+
};

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ at the app level ensures you only create one instance of Shepherd.**
6262
In that component you will want to use `AfterViewInit` to `addSteps` to the Shepherd service.
6363

6464
```typescript
65-
import { Component, AfterViewInit } from '@angular/core';
65+
import { Component, type AfterViewInit } from '@angular/core';
6666
import { ShepherdService } from 'angular-shepherd';
6767
import { steps as defaultSteps, defaultStepOptions} from '../data';
6868

package-lock.json

Lines changed: 35 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"@angular/platform-browser-dynamic": "^19.0.0",
2626
"core-js": "^3.39.0",
2727
"rxjs": "^7.8.1",
28-
"shepherd.js": "^11.2.0",
28+
"shepherd.js": "^14.4.0",
2929
"tslib": "^2.8.0",
3030
"zone.js": "~0.15.0"
3131
},
@@ -58,6 +58,7 @@
5858
"karma-jasmine": "^5.1.0",
5959
"karma-jasmine-html-reporter": "^2.1.0",
6060
"ng-packagr": "^19.0.0",
61+
"prettier": "^3.4.2",
6162
"protractor": "~7.0.0",
6263
"release-it": "^17.10.0",
6364
"ts-node": "~10.9.2",

projects/shepherd-tester/src/app/data.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import Step from 'shepherd.js/src/types/step';
1+
import { type StepOptions } from 'shepherd.js';
22

33
export const builtInButtons = {
44
cancel: {
@@ -20,15 +20,15 @@ export const builtInButtons = {
2020
}
2121
};
2222

23-
export const defaultStepOptions: Step.StepOptions = {
23+
export const defaultStepOptions: StepOptions = {
2424
classes: 'shepherd-theme-arrows custom-default-class',
2525
scrollTo: true,
2626
cancelIcon: {
2727
enabled: true
2828
}
2929
};
3030

31-
export const steps: Step.StepOptions[] = [
31+
export const steps: StepOptions[] = [
3232
{
3333
attachTo: {
3434
element: '.first-element',

projects/shepherd-tester/src/app/shepherd/shepherd.component.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
import { Component, AfterViewInit } from '@angular/core';
1+
import { Component, type AfterViewInit } from '@angular/core';
22
import { ShepherdService } from '../../../../shepherd/src/lib/shepherd.service';
3-
import { steps as defaultSteps, defaultStepOptions} from '../data';
3+
import { steps as defaultSteps, defaultStepOptions } from '../data';
44

55
@Component({
66
selector: 'app-shepherd',
77
templateUrl: './shepherd.component.html',
88
styleUrls: ['./shepherd.component.css'],
9-
standalone: true,
9+
standalone: true
1010
})
1111
export class ShepherdComponent implements AfterViewInit {
12-
13-
constructor(private shepherdService: ShepherdService) { }
12+
constructor(private shepherdService: ShepherdService) {}
1413

1514
ngAfterViewInit() {
1615
this.shepherdService.defaultStepOptions = defaultStepOptions;

projects/shepherd/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ at the app level ensures you only create one instance of Shepherd.**
5959
In that component you will want to use `AfterViewInit` to `addSteps` to the Shepherd service.
6060

6161
```typescript
62-
import { Component, AfterViewInit } from '@angular/core';
62+
import { Component, type AfterViewInit } from '@angular/core';
6363
import { ShepherdService } from 'angular-shepherd';
6464
import { steps as defaultSteps, defaultStepOptions} from '../data';
6565

projects/shepherd/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"url": "https://github.com/rwwagner90"
2121
},
2222
"dependencies": {
23-
"shepherd.js": "^11.0.0"
23+
"shepherd.js": "^14.4.0"
2424
},
2525
"peerDependencies": {
2626
"@angular/common": "^19.0.0",

projects/shepherd/src/lib/shepherd.service.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,7 @@ const steps = [
2929
element: '.test-element',
3030
on: 'bottom'
3131
},
32-
buttons: [
33-
builtInButtons.cancel,
34-
builtInButtons.next
35-
],
32+
buttons: [builtInButtons.cancel, builtInButtons.next],
3633
classes: 'custom-class-name-1 custom-class-name-2',
3734
title: 'Welcome to Ember-Shepherd!',
3835
text: 'Test text',
@@ -53,7 +50,7 @@ describe('ShepherdService', () => {
5350
start() {
5451
expect(true).toBeTruthy('The tour was started');
5552
}
56-
}
53+
};
5754

5855
service.addSteps(steps);
5956

@@ -67,7 +64,10 @@ describe('ShepherdService', () => {
6764
const service: ShepherdService = TestBed.inject(ShepherdService);
6865
const mockTourObject = {
6966
start() {
70-
expect(steps[0].options.scrollToHandler()).toBe('custom scrollToHandler', 'The handler was passed through as an option on the step');
67+
expect(steps[0]?.options.scrollToHandler()).toBe(
68+
'custom scrollToHandler',
69+
'The handler was passed through as an option on the step'
70+
);
7171
}
7272
};
7373

projects/shepherd/src/lib/shepherd.service.ts

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,85 @@
11
import { Injectable } from '@angular/core';
2-
import Shepherd from 'shepherd.js';
2+
import Shepherd, {
3+
type TourOptions,
4+
type StepOptions,
5+
type Tour
6+
} from 'shepherd.js';
37
import { elementIsHidden } from './utils/dom';
48
import { makeButton } from './utils/buttons';
5-
import Step from 'shepherd.js/src/types/step';
9+
10+
interface RequiredElement {
11+
message: string;
12+
selector: string;
13+
title: string;
14+
}
615
@Injectable({
716
providedIn: 'root'
817
})
918
export class ShepherdService {
10-
confirmCancel = false;
11-
confirmCancelMessage: string = null;
12-
defaultStepOptions: Step.StepOptions = {};
13-
errorTitle = null;
19+
confirmCancel: TourOptions['confirmCancel'] = false;
20+
confirmCancelMessage?: TourOptions['confirmCancelMessage'];
21+
defaultStepOptions: StepOptions = {};
22+
errorTitle?: string;
23+
exitOnEsc = true;
1424
isActive = false;
15-
keyboardNavigation = true;
16-
messageForUser: string = null;
25+
keyboardNavigation: TourOptions['keyboardNavigation'] = true;
26+
messageForUser: string | null = null;
1727
modal = false;
18-
requiredElements = [];
28+
requiredElements: Array<RequiredElement> = [];
1929
tourName = undefined;
20-
tourObject: Shepherd.Tour = null;
21-
exitOnEsc = true;
30+
tourObject: Tour | null = null;
2231

23-
constructor () {
24-
}
32+
constructor() {}
2533

2634
/**
2735
* Get the tour object and call back
2836
*/
2937
back() {
30-
this.tourObject.back();
38+
this.tourObject?.back();
3139
}
3240

3341
/**
3442
* Cancel the tour
3543
*/
3644
cancel() {
37-
this.tourObject.cancel();
45+
this.tourObject?.cancel();
3846
}
3947

4048
/**
4149
* Complete the tour
4250
*/
4351
complete() {
44-
this.tourObject.complete();
52+
this.tourObject?.complete();
4553
}
4654

4755
/**
4856
* Hides the current step
4957
*/
5058
hide() {
51-
this.tourObject.hide();
59+
this.tourObject?.hide();
5260
}
5361

5462
/**
5563
* Advance the tour to the next step
5664
*/
5765
next() {
58-
this.tourObject.next();
66+
this.tourObject?.next();
5967
}
6068

6169
/**
6270
* Show a specific step, by passing its id
6371
* @param id The id of the step you want to show
6472
*/
6573
show(id: string | number) {
66-
this.tourObject.show(id);
74+
this.tourObject?.show(id);
6775
}
6876

6977
/**
7078
* Start the tour
7179
*/
7280
start() {
7381
this.isActive = true;
74-
this.tourObject.start();
82+
this.tourObject?.start();
7583
}
7684

7785
/**
@@ -86,24 +94,26 @@ export class ShepherdService {
8694
* Take a set of steps and create a tour object based on the current configuration
8795
* @param steps An array of steps
8896
*/
89-
addSteps(steps: Array<Step.StepOptions>) {
97+
addSteps(steps: Array<StepOptions>) {
9098
this._initialize();
9199
const tour = this.tourObject;
92100

93-
// Return nothing if there are no steps
94-
if (!steps || !Array.isArray(steps) || steps.length === 0) {
101+
// Return nothing if there are no steps or if somehow there is no tour.
102+
if (!tour || !steps || !Array.isArray(steps) || steps.length === 0) {
95103
return;
96104
}
97105

98106
if (!this.requiredElementsPresent()) {
99107
tour.addStep({
100-
buttons: [{
101-
text: 'Exit',
102-
action: tour.cancel
103-
}],
108+
buttons: [
109+
{
110+
text: 'Exit',
111+
action: tour.cancel
112+
}
113+
],
104114
id: 'error',
105115
title: this.errorTitle,
106-
text: [this.messageForUser]
116+
text: [this.messageForUser as string]
107117
});
108118
return;
109119
}
@@ -128,7 +138,10 @@ export class ShepherdService {
128138
this.requiredElements.forEach((element) => {
129139
const selectedElement = document.querySelector(element.selector);
130140

131-
if (allElementsPresent && (!selectedElement || elementIsHidden(selectedElement))) {
141+
if (
142+
allElementsPresent &&
143+
(!selectedElement || elementIsHidden(selectedElement as HTMLElement))
144+
) {
132145
allElementsPresent = false;
133146
this.errorTitle = element.title;
134147
this.messageForUser = element.message;

0 commit comments

Comments
 (0)