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

Change builtInButtons to buttons #241

Merged
merged 9 commits into from
Sep 14, 2018
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
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