Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"use strict";

module.exports = {
arrowParens: "always",
proseWrap: "always",
trailingComma: "none",
singleQuote: true,
};
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ at the app level ensures you only create one instance of Shepherd.**
In that component you will want to use `AfterViewInit` to `addSteps` to the Shepherd service.

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

Expand Down
53 changes: 35 additions & 18 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@angular/platform-browser-dynamic": "^19.0.0",
"core-js": "^3.39.0",
"rxjs": "^7.8.1",
"shepherd.js": "^11.2.0",
"shepherd.js": "^14.4.0",
"tslib": "^2.8.0",
"zone.js": "~0.15.0"
},
Expand Down Expand Up @@ -58,6 +58,7 @@
"karma-jasmine": "^5.1.0",
"karma-jasmine-html-reporter": "^2.1.0",
"ng-packagr": "^19.0.0",
"prettier": "^3.4.2",
"protractor": "~7.0.0",
"release-it": "^17.10.0",
"ts-node": "~10.9.2",
Expand Down
6 changes: 3 additions & 3 deletions projects/shepherd-tester/src/app/data.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Step from 'shepherd.js/src/types/step';
import { type StepOptions } from 'shepherd.js';

export const builtInButtons = {
cancel: {
Expand All @@ -20,15 +20,15 @@ export const builtInButtons = {
}
};

export const defaultStepOptions: Step.StepOptions = {
export const defaultStepOptions: StepOptions = {
classes: 'shepherd-theme-arrows custom-default-class',
scrollTo: true,
cancelIcon: {
enabled: true
}
};

export const steps: Step.StepOptions[] = [
export const steps: StepOptions[] = [
{
attachTo: {
element: '.first-element',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { Component, AfterViewInit } from '@angular/core';
import { Component, type AfterViewInit } from '@angular/core';
import { ShepherdService } from '../../../../shepherd/src/lib/shepherd.service';
import { steps as defaultSteps, defaultStepOptions} from '../data';
import { steps as defaultSteps, defaultStepOptions } from '../data';

@Component({
selector: 'app-shepherd',
templateUrl: './shepherd.component.html',
styleUrls: ['./shepherd.component.css'],
standalone: true,
standalone: true
})
export class ShepherdComponent implements AfterViewInit {

constructor(private shepherdService: ShepherdService) { }
constructor(private shepherdService: ShepherdService) {}

ngAfterViewInit() {
this.shepherdService.defaultStepOptions = defaultStepOptions;
Expand Down
2 changes: 1 addition & 1 deletion projects/shepherd/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ at the app level ensures you only create one instance of Shepherd.**
In that component you will want to use `AfterViewInit` to `addSteps` to the Shepherd service.

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

Expand Down
2 changes: 1 addition & 1 deletion projects/shepherd/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"url": "https://github.com/rwwagner90"
},
"dependencies": {
"shepherd.js": "^11.0.0"
"shepherd.js": "^14.4.0"
},
"peerDependencies": {
"@angular/common": "^19.0.0",
Expand Down
12 changes: 6 additions & 6 deletions projects/shepherd/src/lib/shepherd.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,7 @@ const steps = [
element: '.test-element',
on: 'bottom'
},
buttons: [
builtInButtons.cancel,
builtInButtons.next
],
buttons: [builtInButtons.cancel, builtInButtons.next],
classes: 'custom-class-name-1 custom-class-name-2',
title: 'Welcome to Ember-Shepherd!',
text: 'Test text',
Expand All @@ -53,7 +50,7 @@ describe('ShepherdService', () => {
start() {
expect(true).toBeTruthy('The tour was started');
}
}
};

service.addSteps(steps);

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

Expand Down
71 changes: 42 additions & 29 deletions projects/shepherd/src/lib/shepherd.service.ts
Original file line number Diff line number Diff line change
@@ -1,77 +1,85 @@
import { Injectable } from '@angular/core';
import Shepherd from 'shepherd.js';
import Shepherd, {
type TourOptions,
type StepOptions,
type Tour
} from 'shepherd.js';
import { elementIsHidden } from './utils/dom';
import { makeButton } from './utils/buttons';
import Step from 'shepherd.js/src/types/step';

interface RequiredElement {
message: string;
selector: string;
title: string;
}
@Injectable({
providedIn: 'root'
})
export class ShepherdService {
confirmCancel = false;
confirmCancelMessage: string = null;
defaultStepOptions: Step.StepOptions = {};
errorTitle = null;
confirmCancel: TourOptions['confirmCancel'] = false;
confirmCancelMessage?: TourOptions['confirmCancelMessage'];
defaultStepOptions: StepOptions = {};
errorTitle?: string;
exitOnEsc = true;
isActive = false;
keyboardNavigation = true;
messageForUser: string = null;
keyboardNavigation: TourOptions['keyboardNavigation'] = true;
messageForUser: string | null = null;
modal = false;
requiredElements = [];
requiredElements: Array<RequiredElement> = [];
tourName = undefined;
tourObject: Shepherd.Tour = null;
exitOnEsc = true;
tourObject: Tour | null = null;

constructor () {
}
constructor() {}

/**
* Get the tour object and call back
*/
back() {
this.tourObject.back();
this.tourObject?.back();
}

/**
* Cancel the tour
*/
cancel() {
this.tourObject.cancel();
this.tourObject?.cancel();
}

/**
* Complete the tour
*/
complete() {
this.tourObject.complete();
this.tourObject?.complete();
}

/**
* Hides the current step
*/
hide() {
this.tourObject.hide();
this.tourObject?.hide();
}

/**
* Advance the tour to the next step
*/
next() {
this.tourObject.next();
this.tourObject?.next();
}

/**
* Show a specific step, by passing its id
* @param id The id of the step you want to show
*/
show(id: string | number) {
this.tourObject.show(id);
this.tourObject?.show(id);
}

/**
* Start the tour
*/
start() {
this.isActive = true;
this.tourObject.start();
this.tourObject?.start();
}

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

// Return nothing if there are no steps
if (!steps || !Array.isArray(steps) || steps.length === 0) {
// Return nothing if there are no steps or if somehow there is no tour.
if (!tour || !steps || !Array.isArray(steps) || steps.length === 0) {
return;
}

if (!this.requiredElementsPresent()) {
tour.addStep({
buttons: [{
text: 'Exit',
action: tour.cancel
}],
buttons: [
{
text: 'Exit',
action: tour.cancel
}
],
id: 'error',
title: this.errorTitle,
text: [this.messageForUser]
text: [this.messageForUser as string]
});
return;
}
Expand All @@ -128,7 +138,10 @@ export class ShepherdService {
this.requiredElements.forEach((element) => {
const selectedElement = document.querySelector(element.selector);

if (allElementsPresent && (!selectedElement || elementIsHidden(selectedElement))) {
if (
allElementsPresent &&
(!selectedElement || elementIsHidden(selectedElement as HTMLElement))
) {
allElementsPresent = false;
this.errorTitle = element.title;
this.messageForUser = element.message;
Expand Down
Loading
Loading