kamrify commited on
Commit
df9f42f
·
1 Parent(s): 6d6655e

Allow displaying buttons on single highlight elements

Browse files
.eslintrc.json CHANGED
@@ -4,7 +4,6 @@
4
  "browser": true
5
  },
6
  "rules": {
7
- "no-console": "off",
8
  "no-underscore-dangle": "off",
9
  "no-plusplus": "off",
10
  "no-cond-assign": "off",
 
4
  "browser": true
5
  },
6
  "rules": {
 
7
  "no-underscore-dangle": "off",
8
  "no-plusplus": "off",
9
  "no-cond-assign": "off",
src/common/constants.js CHANGED
@@ -27,6 +27,8 @@ export const CLASS_CLOSE_BTN = 'driver-close-btn';
27
  export const CLASS_NEXT_STEP_BTN = 'driver-next-btn';
28
  export const CLASS_PREV_STEP_BTN = 'driver-prev-btn';
29
  export const CLASS_BTN_DISABLED = 'driver-disabled';
 
 
30
 
31
  // NOTE: It must match the one set in the animations in CSS file
32
  export const ANIMATION_DURATION_MS = 300;
@@ -37,9 +39,9 @@ export const POPOVER_HTML = (className = '') => `
37
  <div class="${CLASS_POPOVER_TIP}"></div>
38
  <div class="${CLASS_POPOVER_TITLE}">Popover Title</div>
39
  <div class="${CLASS_POPOVER_DESCRIPTION}">Popover Description</div>
40
- <div class="${CLASS_POPOVER_FOOTER}">
41
  <button class="${CLASS_CLOSE_BTN}">Close</button>
42
- <span class="driver-btn-group">
43
  <button class="${CLASS_PREV_STEP_BTN}">&larr; Previous</button>
44
  <button class="${CLASS_NEXT_STEP_BTN}">Next &rarr;</button>
45
  </span>
 
27
  export const CLASS_NEXT_STEP_BTN = 'driver-next-btn';
28
  export const CLASS_PREV_STEP_BTN = 'driver-prev-btn';
29
  export const CLASS_BTN_DISABLED = 'driver-disabled';
30
+ export const CLASS_CLOSE_ONLY_BTN = 'driver-close-only-btn';
31
+ export const CLASS_NAVIGATION_BTNS = 'driver-navigation-btns';
32
 
33
  // NOTE: It must match the one set in the animations in CSS file
34
  export const ANIMATION_DURATION_MS = 300;
 
39
  <div class="${CLASS_POPOVER_TIP}"></div>
40
  <div class="${CLASS_POPOVER_TITLE}">Popover Title</div>
41
  <div class="${CLASS_POPOVER_DESCRIPTION}">Popover Description</div>
42
+ <div class="driver-clearfix ${CLASS_POPOVER_FOOTER}">
43
  <button class="${CLASS_CLOSE_BTN}">Close</button>
44
+ <span class="driver-btn-group ${CLASS_NAVIGATION_BTNS}">
45
  <button class="${CLASS_PREV_STEP_BTN}">&larr; Previous</button>
46
  <button class="${CLASS_NEXT_STEP_BTN}">Next &rarr;</button>
47
  </span>
src/core/popover.js CHANGED
@@ -2,6 +2,7 @@ import Element from './element';
2
  import {
3
  CLASS_BTN_DISABLED,
4
  CLASS_CLOSE_BTN,
 
5
  CLASS_NEXT_STEP_BTN,
6
  CLASS_POPOVER_DESCRIPTION,
7
  CLASS_POPOVER_FOOTER,
@@ -190,12 +191,27 @@ export default class Popover extends Element {
190
  this.prevBtnNode.innerHTML = this.options.prevBtnText;
191
  this.closeBtnNode.innerHTML = this.options.closeBtnText;
192
 
 
 
193
  // If there was only one item, hide the buttons
194
- if (!this.options.showButtons || !this.options.totalCount || this.options.totalCount === 1) {
195
  this.footerNode.style.display = 'none';
196
  return;
197
  }
198
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  this.footerNode.style.display = 'block';
200
  if (this.options.isFirst) {
201
  this.prevBtnNode.classList.add(CLASS_BTN_DISABLED);
 
2
  import {
3
  CLASS_BTN_DISABLED,
4
  CLASS_CLOSE_BTN,
5
+ CLASS_CLOSE_ONLY_BTN,
6
  CLASS_NEXT_STEP_BTN,
7
  CLASS_POPOVER_DESCRIPTION,
8
  CLASS_POPOVER_FOOTER,
 
191
  this.prevBtnNode.innerHTML = this.options.prevBtnText;
192
  this.closeBtnNode.innerHTML = this.options.closeBtnText;
193
 
194
+ const hasSteps = this.options.totalCount && this.options.totalCount !== 1;
195
+
196
  // If there was only one item, hide the buttons
197
+ if (!this.options.showButtons) {
198
  this.footerNode.style.display = 'none';
199
  return;
200
  }
201
 
202
+ // If this is just a single highlighted element i.e. there
203
+ // are no other steps to go to – just hide the navigation buttons
204
+ if (!hasSteps) {
205
+ this.nextBtnNode.style.display = 'none';
206
+ this.prevBtnNode.style.display = 'none';
207
+ this.closeBtnNode.classList.add(CLASS_CLOSE_ONLY_BTN);
208
+ } else {
209
+ // @todo modify CSS to use block
210
+ this.nextBtnNode.style.display = 'inline-block';
211
+ this.prevBtnNode.style.display = 'inline-block';
212
+ this.closeBtnNode.classList.remove(CLASS_CLOSE_ONLY_BTN);
213
+ }
214
+
215
  this.footerNode.style.display = 'block';
216
  if (this.options.isFirst) {
217
  this.prevBtnNode.classList.add(CLASS_BTN_DISABLED);
src/driver.scss CHANGED
@@ -107,8 +107,7 @@ div#driver-popover-item {
107
 
108
  .driver-popover-footer {
109
  display: block;
110
- clear: both;
111
- margin-top: 5px;
112
 
113
  button {
114
  display: inline-block;
@@ -123,7 +122,6 @@ div#driver-popover-item {
123
  background-color: $button-bg;
124
  border-radius: 2px;
125
  zoom: 1;
126
- margin: 10px 0 0;
127
  line-height: 1.3;
128
  }
129
 
@@ -137,6 +135,10 @@ div#driver-popover-item {
137
  float: left;
138
  }
139
 
 
 
 
 
140
  .driver-btn-group {
141
  float: right;
142
  }
@@ -162,6 +164,17 @@ div#driver-popover-item {
162
  }
163
  }
164
 
 
 
 
 
 
 
 
 
 
 
 
165
  .driver-stage-no-animation {
166
  -webkit-transition: none !important;
167
  -moz-transition: none !important;
 
107
 
108
  .driver-popover-footer {
109
  display: block;
110
+ margin-top: 10px;
 
111
 
112
  button {
113
  display: inline-block;
 
122
  background-color: $button-bg;
123
  border-radius: 2px;
124
  zoom: 1;
 
125
  line-height: 1.3;
126
  }
127
 
 
135
  float: left;
136
  }
137
 
138
+ .driver-close-only-btn {
139
+ float: right;
140
+ }
141
+
142
  .driver-btn-group {
143
  float: right;
144
  }
 
164
  }
165
  }
166
 
167
+ .driver-clearfix:before {
168
+ content: "";
169
+ display: table;
170
+ }
171
+
172
+ .driver-clearfix:after {
173
+ clear: both;
174
+ content: "";
175
+ display: table;
176
+ }
177
+
178
  .driver-stage-no-animation {
179
  -webkit-transition: none !important;
180
  -moz-transition: none !important;
src/index.js CHANGED
@@ -182,13 +182,17 @@ export default class Driver {
182
  return;
183
  }
184
 
185
- // Arrow keys to only perform if it is stepped introduction
186
- if (this.steps.length !== 0) {
187
- if (event.keyCode === RIGHT_KEY_CODE) {
188
- this.handleNext();
189
- } else if (event.keyCode === LEFT_KEY_CODE) {
190
- this.handlePrevious();
191
- }
 
 
 
 
192
  }
193
  }
194
 
@@ -226,7 +230,7 @@ export default class Driver {
226
 
227
  // Call the bound `onNext` handler if available
228
  const currentStep = this.steps[this.currentStep];
229
- if (currentStep.options.onNext) {
230
  currentStep.options.onNext(this.overlay.highlightedElement);
231
  }
232
 
@@ -246,7 +250,7 @@ export default class Driver {
246
 
247
  // Call the bound `onPrevious` handler if available
248
  const currentStep = this.steps[this.currentStep];
249
- if (currentStep.options.onPrevious) {
250
  currentStep.options.onPrevious(this.overlay.highlightedElement);
251
  }
252
 
@@ -357,7 +361,7 @@ export default class Driver {
357
  * @private
358
  */
359
  prepareElementFromStep(currentStep, allSteps = [], index = 0) {
360
- let elementOptions = {};
361
  let querySelector = currentStep;
362
 
363
  // If the `currentStep` is step definition
@@ -388,23 +392,19 @@ export default class Driver {
388
  ].filter(c => c).join(' ');
389
 
390
  const popoverOptions = {
391
- ...this.options,
392
  ...elementOptions.popover,
393
  className: mergedClassNames,
394
  totalCount: allSteps.length,
395
  currentIndex: index,
396
  isFirst: index === 0,
397
- isLast: index === allSteps.length - 1,
398
  };
399
 
400
  popover = new Popover(popoverOptions, this.window, this.document);
401
  }
402
 
403
- const stageOptions = {
404
- ...this.options,
405
- ...elementOptions,
406
- };
407
-
408
  const stage = new Stage(stageOptions, this.window, this.document);
409
 
410
  return new Element({
 
182
  return;
183
  }
184
 
185
+ // If there is no highlighted element or there is a highlighted element
186
+ // without popover or if the popover does not allow buttons - ignore
187
+ const highlightedElement = this.getHighlightedElement();
188
+ if (!highlightedElement || !highlightedElement.popover || !highlightedElement.popover.options.showButtons) {
189
+ return;
190
+ }
191
+
192
+ if (event.keyCode === RIGHT_KEY_CODE) {
193
+ this.handleNext();
194
+ } else if (event.keyCode === LEFT_KEY_CODE) {
195
+ this.handlePrevious();
196
  }
197
  }
198
 
 
230
 
231
  // Call the bound `onNext` handler if available
232
  const currentStep = this.steps[this.currentStep];
233
+ if (currentStep && currentStep.options && currentStep.options.onNext) {
234
  currentStep.options.onNext(this.overlay.highlightedElement);
235
  }
236
 
 
250
 
251
  // Call the bound `onPrevious` handler if available
252
  const currentStep = this.steps[this.currentStep];
253
+ if (currentStep && currentStep.options && currentStep.options.onPrevious) {
254
  currentStep.options.onPrevious(this.overlay.highlightedElement);
255
  }
256
 
 
361
  * @private
362
  */
363
  prepareElementFromStep(currentStep, allSteps = [], index = 0) {
364
+ let elementOptions = { ...this.options };
365
  let querySelector = currentStep;
366
 
367
  // If the `currentStep` is step definition
 
392
  ].filter(c => c).join(' ');
393
 
394
  const popoverOptions = {
395
+ ...elementOptions,
396
  ...elementOptions.popover,
397
  className: mergedClassNames,
398
  totalCount: allSteps.length,
399
  currentIndex: index,
400
  isFirst: index === 0,
401
+ isLast: allSteps.length === 0 || index === allSteps.length - 1, // Only one item or last item
402
  };
403
 
404
  popover = new Popover(popoverOptions, this.window, this.document);
405
  }
406
 
407
+ const stageOptions = { ...elementOptions };
 
 
 
 
408
  const stage = new Stage(stageOptions, this.window, this.document);
409
 
410
  return new Element({