Skip to content

Commit

Permalink
Change builtInButtons to buttons (#241)
Browse files Browse the repository at this point in the history
* change all instances for builtInButtons to align with Shepherd docs for config

* fix tests

* update docs on buttons and change makeButton logic

* Update buttons README

* Update tour.js

* Fix lint

* Fix options map

* Update tests

* Move to separate file
  • Loading branch information
chuckcarpenter authored and RobbieTheWagner committed Sep 14, 2018
1 parent 302a120 commit dcc1f25
Show file tree
Hide file tree
Showing 9 changed files with 840 additions and 359 deletions.
35 changes: 3 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ this.get('tour').set('steps', [
});
});
},
builtInButtons: [
buttons: [
{
classes: 'shepherd-button-secondary',
text: 'Exit',
Expand Down Expand Up @@ -218,38 +218,9 @@ A function that returns a promise. When the promise resolves, the rest of the `s
> **default value:** `null`

##### builtInButtons

These are the standard button types supported by Shepherd. Just set type to `next`, `back`, or `cancel`, then set the text and classes as normal.

Custom actions can also be used by using an action method instead of a type. For example:

``` javascript
...
builtInButtons: [
{
classes: 'shepherd-button-secondary',
text: 'Exit',
type: 'cancel'
},
{
classes: 'shepherd-button-primary',
text: 'Next',
type: 'next'
},
{
classes: 'shepherd-button-primary',
text: 'Custom action',
action() {
console.log('custom action called');
}
}
]
...
```

> **required:** `yes`
##### buttons

There are some standard button types supported by ember-shepherd. Just set `type` to `'next'`, `'back'`, or `'cancel'`, then set the `text` and `classes` as normal. These will automatically be bound to the Shepherd functions. If no type is passed, a normal Shepherd button will be created.

##### classes

Expand Down
42 changes: 24 additions & 18 deletions addon/services/tour.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* eslint-disable ember/avoid-leaking-state-in-ember-objects, ember/no-observers */
import { assert } from '@ember/debug';
import { get, observer, set } from '@ember/object';
import { isEmpty, isPresent } from '@ember/utils';
import Service from '@ember/service';
Expand Down Expand Up @@ -91,7 +90,9 @@ export default Service.extend(Evented, {
* @param {string} completeOrCancel 'complete' or 'cancel'
*/
onTourFinish(completeOrCancel) {
set(this, 'isActive', false);
if (!this.isDestroyed) {
set(this, 'isActive', false);
}
this.cleanup();
this.trigger(completeOrCancel);
},
Expand Down Expand Up @@ -188,27 +189,32 @@ export default Service.extend(Evented, {
/**
* Creates a button of the specified type, with the given classes and text
*
* @param type The type of button cancel, back, or next
* @param classes Classes to apply to the button
* @param text The text for the button
* @param action The action to call
* @param button.type The type of button cancel, back, or next
* @param button.classes Classes to apply to the button
* @param button.text The text for the button
* @param button.action The action to call
* @returns {{action: *, classes: *, text: *}}
* @private
*/
makeButton({ type, classes, text, action }) {
makeButton(button) {
const { type, classes, text } = button;

if (!type) {
return button;
}

const builtInButtonTypes = ['back', 'cancel', 'next'];
if (builtInButtonTypes.includes(type)) {
action = run.bind(this, function() {
const action = run.bind(this, function() {
this[type]();
});
} else {
action = action || function() {};

return {
action,
classes,
text
};
}
return {
action,
classes,
text
};
},

/**
Expand Down Expand Up @@ -291,7 +297,6 @@ export default Service.extend(Evented, {
stepsChange: observer('steps', function() {
this.initialize();
const steps = get(this, 'steps');

const tour = get(this, 'tourObject');

// Return nothing if there are no steps
Expand All @@ -315,8 +320,9 @@ export default Service.extend(Evented, {
steps.forEach((step, index) => {
const { id, options } = step;

assert('You must either pass an array of builtInButtons or `false`, undefined is not supported', options.builtInButtons !== undefined);
options.buttons = (options.builtInButtons !== false) ? options.builtInButtons.map(this.makeButton, this) : false;
if (options.buttons) {
options.buttons = options.buttons.map(this.makeButton, this);
}
options.attachTo = this.normalizeAttachTo(options.attachTo);
tour.addStep(id, options);

Expand Down
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"broccoli-asset-rev": "^2.7.0",
"codeclimate-test-reporter": "^0.5.0",
"ember-cli": "~3.4.1",
"ember-cli-code-coverage": "^1.0.0-beta.4",
"ember-cli-code-coverage": "^1.0.0-beta.5",
"ember-cli-dependency-checker": "^3.0.0",
"ember-cli-deploy": "^1.0.2",
"ember-cli-deploy-build": "^1.1.0",
Expand All @@ -83,8 +83,6 @@
"ember-maybe-import-regenerator": "^0.1.6",
"ember-prism": "0.3.0",
"ember-resolver": "^5.0.1",
"ember-sinon": "^2.2.0",
"ember-sinon-qunit": "^3.2.0",
"ember-source": "~3.4.0",
"ember-source-channel-url": "^1.1.0",
"ember-try": "^1.0.0",
Expand Down
39 changes: 39 additions & 0 deletions tests/acceptance/buttons-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { module, test } from 'qunit';
import { visit, click } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';

/**
* This is in a separate file because it randomly fails when not run on its own
*/
module('Acceptance | Buttons tests', function(hooks) {
let tour;

setupApplicationTest(hooks);

hooks.beforeEach(function() {
tour = this.owner.lookup('service:tour');

tour.set('confirmCancel', false);
tour.set('modal', false);
});

hooks.afterEach(async function() {
return await tour.cancel();
});

test('Tour next, back, and cancel buttons work', async function(assert) {
assert.expect(3);

await visit('/');

await click('.toggleHelpModal');
await click(document.querySelector('.shepherd-element[style*="display: block"] .next-button'));
assert.ok(document.querySelector('.shepherd-element[style*="display: block"] .back-button'), 'Ensure that the back button appears');

await click(document.querySelector('.shepherd-element[style*="display: block"] .back-button'));
assert.notOk(document.querySelector('.shepherd-element[style*="display: block"] .back-button'), 'Ensure that the back button disappears');

await click(document.querySelector('.shepherd-element[style*="display: block"] .cancel-button'));
assert.notOk(document.querySelector('.shepherd-element [class^=shepherd-button]'), 'Ensure that all buttons are gone, after exit');
});
});
Loading

0 comments on commit dcc1f25

Please sign in to comment.