Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify addStep API #464

Merged
merged 1 commit into from
Jul 26, 2019
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
5 changes: 3 additions & 2 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ <h3>Example</h3>
}
});

tour.addStep('creating', {
tour.addStep({
title: 'Creating a Shepherd Tour',
text: `Creating a Shepherd tour is easy. too!\
Just create a \`Tour\` instance, and add as many steps as you want.`,
Expand All @@ -71,7 +71,8 @@ <h3>Example</h3>
action: shepherd.next,
text: 'Next'
}
]
],
id: 'creating'
});

tour.start();
Expand Down
85 changes: 51 additions & 34 deletions demo/js/welcome.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
},
useModalOverlay: true
});
shepherd.addStep('welcome', {
shepherd.addStep({
text: '\n <p>\n Shepherd is a JavaScript library for guiding users through your app.\n It uses <a href="https://atomiks.github.io/tippyjs//" data-test-tippy-link>Tippy.js</a>,\n another open source library, to render dialogs for each tour "step".\n </p>\n \n <p>\n Among many things, Tippy makes sure your steps never end up off screen or cropped by an overflow.\n (Try resizing your browser to see what we mean.)\n </p>\n <p>\n It also offers a robust API for styling animations of steps\n as they enter and exit the view.\n </p>',
attachTo: {
element: '.hero-welcome',
Expand All @@ -44,9 +44,11 @@
{
action: shepherd.next,
text: 'Next'
}]
}
],
id: 'welcome'
});
shepherd.addStep('including', {
shepherd.addStep({
title: 'Including',
text: 'Including Shepherd is easy! Just include shepherd.js. The styles are bundled with the JS.',
attachTo: {
Expand All @@ -58,13 +60,15 @@
action: shepherd.back,
secondary: true,
text: 'Back'
}, {
},
{
action: shepherd.next,
text: 'Next'
}
]
],
id: 'including'
});
shepherd.addStep('creating', {
shepherd.addStep({
title: 'Creating a Shepherd Tour',
text: 'Creating a Shepherd tour is easy. too! ' + 'Just create a \`Tour\` instance, and add as many steps as you want.',
attachTo: {
Expand All @@ -81,51 +85,64 @@
action: shepherd.next,
text: 'Next'
}
]
],
id: 'creating'
});
shepherd.addStep('attaching', {
shepherd.addStep({
title: 'Attaching to Elements',
text: 'Your tour steps can target and attach to elements in DOM (like this step).',
attachTo: {
element: '.hero-example',
on: 'left'
},
buttons: [{
action: shepherd.back,
secondary: true,
text: 'Back'
}, {
action: shepherd.next,
text: 'Next'
}]
buttons: [
{
action: shepherd.back,
secondary: true,
text: 'Back'
},
{
action: shepherd.next,
text: 'Next'
}
],
id: 'attaching'
});
shepherd.addStep('centered-example', {
shepherd.addStep({
title: 'Centered Shepherd Element',
text: 'But attachment is totally optional!\n Without a target, a tour step will create an element that\'s centered within the view. Check out the <a href="https://shepherdjs.dev/docs/">documentation</a> to learn more.',
buttons: [{
action: shepherd.back,
secondary: true,
text: 'Back'
}, {
action: shepherd.next,
text: 'Next'
}]
buttons: [
{
action: shepherd.back,
secondary: true,
text: 'Back'
},
{
action: shepherd.next,
text: 'Next'
}
],
id: 'centered-example'
});
shepherd.addStep('followup', {
shepherd.addStep({
title: 'Learn more',
text: 'Star Shepherd on Github so you remember it for your next project',
attachTo: {
element: '.hero-followup',
on: 'top'
},
buttons: [{
action: shepherd.back,
secondary: true,
text: 'Back'
}, {
action: shepherd.next,
text: 'Done'
}],
buttons: [
{
action: shepherd.back,
secondary: true,
text: 'Back'
},
{
action: shepherd.next,
text: 'Done'
}
],
id: 'followup',
modalOverlayOpeningPadding: '10'
});
return shepherd;
Expand Down
13 changes: 8 additions & 5 deletions docs-src/tutorials/02-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ to all this tour's steps by default.
Next, add your steps:

```javascript
tour.addStep('example-step', {
tour.addStep({
id: 'example-step',
text: 'This step is attached to the bottom of the <code>.example-css-selector</code> element.',
attachTo: {
element: '.example-css-selector',
Expand Down Expand Up @@ -113,7 +114,7 @@ dynamically generated `id` property -- which is also set on the `body` element a

##### Tour Methods

- `addStep(id, options)`: Creates a new Step object with options, and returns the `Step` instance it created. If you'd like you can also just pass an options hash which includes `id` as a key.
- `addStep(options)`: Creates a new Step object with options, and returns the `Step` instance it created.
If the options hash doesn't include an `id`, one will be generated.
You can also pass an existing `Step` instance rather than `options`, but note that Shepherd does not support a Step being attached to multiple Tours.
- `getById(id)`: Return a step with a specific id
Expand All @@ -136,7 +137,7 @@ You can also pass an existing `Step` instance rather than `options`, but note th
- `show`: Triggered with a hash of the `step` and the `previous` step
- `start`

Steps are instances of the Step object. They are generally created by the `Tour::addStep` method, which returns the `Step` instance it
Steps are instances of the Step object. They are generally created by the `Tour::addStep` method, which returns the `Step` instance it
created.

#### Steps
Expand Down Expand Up @@ -193,6 +194,7 @@ the step will execute. For example:
For example: `{selector: '.some-element', event: 'click'}`. It doesn't have to be an event inside the tour, it can be any event fired on any element on the page.
You can also always manually advance the Tour by calling `myTour.next()`.
- `highlightClass`: An extra class to apply to the `attachTo` element when it is highlighted (that is, when its step is active). You can then target that selector in your CSS.
- `id`: The string to use as the `id` for the step. If an id is not passed one will be generated.
- `showCancelLink`: Should a cancel "✕" be shown in the header of the step?
- `showOn`: A function that, when it returns true, will show the step. If it returns false, the step will be skipped.
- `scrollTo`: Should the element be scrolled to when this step is shown?
Expand Down Expand Up @@ -239,7 +241,7 @@ You can use the `advanceOn` option, or the Next button, to advance steps. If yo
complex user action, you can do the following:

```javascript
const myStep = myTour.addStep('my-step', options);
const myStep = myTour.addStep(options);

yourApp.on('some-event', () => {
if (myStep.isOpen()){
Expand Down Expand Up @@ -281,7 +283,8 @@ By default, Shepherd will generate and position an "arrow" element that points t
of a step. This is done by setting [Tippy's `arrow` option](https://atomiks.github.io/tippyjs/#arrow-option) to `true` on each ``Step.options.tippyOptions` &mdash; but you can disable the arrow manually by setting it to false:

```js
myTour.addStep('Step 1', {
myTour.addStep({
id: 'Step 1',
tippyOptions: {
arrow: false
}
Expand Down
1 change: 1 addition & 0 deletions src/js/step.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export class Step extends Evented {
* @param {string} options.classes A string of extra classes to add to the step's content element.
* @param {string} options.highlightClass An extra class to apply to the `attachTo` element when it is
* highlighted (that is, when its step is active). You can then target that selector in your CSS.
* @param {string} options.id The string to use as the `id` for the step.
* @param {Object} options.tippyOptions Extra [options to pass to tippy.js]{@link https://atomiks.github.io/tippyjs/#all-options}
* @param {boolean|Object} options.scrollTo Should the element be scrolled to when this step is shown? If true, uses the default `scrollIntoView`,
* if an object, passes that object as the params to `scrollIntoView` i.e. `{behavior: 'smooth', block: 'center'}`
Expand Down
28 changes: 6 additions & 22 deletions src/js/tour.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import tippy from 'tippy.js';
import { Evented } from './evented.js';
import { Step } from './step.jsx';
import autoBind from './utils/auto-bind';
import { isFunction, isNumber, isString, isUndefined } from './utils/type-check';
import { isFunction, isString } from './utils/type-check';
import { defaults as tooltipDefaults } from './utils/tooltip-defaults';
import { cleanupSteps } from './utils/cleanup';
import { normalizePrefix } from './utils/general';
Expand Down Expand Up @@ -81,25 +81,14 @@ export class Tour extends Evented {

/**
* Adds a new step to the tour
* @param {Object|Number|Step|String} arg1
* When arg2 is defined, arg1 can either be a string or number, to use for the `id` for the step
* When arg2 is undefined, arg1 is either an object containing step options or a Step instance
* @param {Object|Step} arg2 An object containing step options or a Step instance
* @param {Object|Step} options An object containing step options or a Step instance
* @return {Step} The newly added step
*/
addStep(arg1, arg2) {
let name, step;

// If we just have one argument, we can assume it is an object of step options, with an id
if (isUndefined(arg2)) {
step = arg1;
} else {
name = arg1;
step = arg2;
}
addStep(options) {
let step = options;

if (!(step instanceof Step)) {
step = this._setupStep(step, name);
step = this._setupStep(step);
} else {
step.tour = this;
}
Expand Down Expand Up @@ -303,15 +292,10 @@ export class Tour extends Evented {
/**
* Setup a new step object
* @param {Object} stepOptions The object describing the options for the step
* @param {String|Number} name The string or number to use as the `id` for the step
* @return {Step} The step instance
* @private
*/
_setupStep(stepOptions, name) {
if (isString(name) || isNumber(name)) {
stepOptions.id = name.toString();
}

_setupStep(stepOptions) {
stepOptions = Object.assign({}, this.options.defaultStepOptions, stepOptions);

return new Step(this, stepOptions);
Expand Down
9 changes: 3 additions & 6 deletions src/types/tour.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,10 @@ declare class Tour extends Evented {

/**
* Adds a new step to the tour
* @param arg1
* When arg2 is defined, arg1 can either be a string or number, to use for the `id` for the step
* When arg2 is undefined, arg1 is either an object containing step options or a Step instance
* @param arg2 An object containing step options or a Step instance
* @param options An object containing step options or a Step instance
* @return The newly added step
*/
addStep(arg1: Step | Step.StepOptions | number | string, arg2: Step | Step.StepOptions): Step;
addStep(options: Step | Step.StepOptions): Step;

/**
* Go to the previous step in the tour
Expand Down Expand Up @@ -130,4 +127,4 @@ declare class Tour extends Evented {
start(): void;
}

export = Tour;
export = Tour;
10 changes: 5 additions & 5 deletions test/cypress/utils/default-steps.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
export default function(shepherd) {
return [
{
id: 'welcome',
options: {
text: `
<p>
Expand Down Expand Up @@ -33,11 +32,11 @@ export default function(shepherd) {
classes: 'shepherd-button-example-primary',
text: 'Next'
}
]
],
id: 'welcome'
}
},
{
id: 'including',
options: {
title: 'Including',
text: 'Including Shepherd is easy! Just include shepherd.js. The styles are bundled with the JS.',
Expand All @@ -56,11 +55,11 @@ export default function(shepherd) {
text: 'Next'
}
],
id: 'including',
classes: 'shepherd-step-element second-step'
}
},
{
id: 'example',
options: {
title: 'Example Shepherd',
text: 'Creating a Shepherd is easy too! Just create Shepherd and add as many steps as you want. Check out the <a href="https://shepherdjs.dev/docs/">documentation</a> to learn more.',
Expand All @@ -79,11 +78,11 @@ export default function(shepherd) {
text: 'Next'
}
],
id: 'example',
classes: 'shepherd-step-element third-step'
}
},
{
id: 'followup',
options: {
title: 'Learn more',
text: 'Star Shepherd on Github so you remember it for your next project',
Expand All @@ -102,6 +101,7 @@ export default function(shepherd) {
text: 'Done'
}
],
id: 'followup',
classes: 'shepherd-step-element fourth-step'
}
}
Expand Down
4 changes: 2 additions & 2 deletions test/cypress/utils/setup-tour.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export default function(Shepherd, globalDefaults, customSteps, otherOptions) {
const steps = typeof customSteps === 'function' ? customSteps(shepherd) : defaultSteps(shepherd);

steps.forEach((step) => {
const { id, options } = step;
shepherd.addStep(id, options);
const { options } = step;
shepherd.addStep(options);
});

return shepherd;
Expand Down
5 changes: 3 additions & 2 deletions test/dummy/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ <h3>Example</h3>
}
});

tour.addStep('example', {
tour.addStep({
title: 'Example Shepherd',
text: 'Creating a Shepherd is easy too! Just create ...',
attachTo: {
Expand All @@ -62,7 +62,8 @@ <h3>Example</h3>
advanceOn: {
selector: '.docs-link',
event: 'click'
}
},
id: 'example'
});

tour.start();
Expand Down
Loading