diff --git a/README.md b/README.md
index ae34fba..1b1a043 100644
--- a/README.md
+++ b/README.md
@@ -2,15 +2,15 @@
Journey.js
[![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Journey.js%2C%20a%20free%20JavaScript%journey%builder&url=https://github.com/williamtroup/Journey.js&hashtags=javascript,html,journey,guide)
-[![npm](https://img.shields.io/badge/npmjs-v0.2.1-blue)](https://www.npmjs.com/package/jjourney.js)
-[![nuget](https://img.shields.io/badge/nuget-v0.2.1-purple)](https://www.nuget.org/packages/jJourney.js/)
+[![npm](https://img.shields.io/badge/npmjs-v0.3.0-blue)](https://www.npmjs.com/package/jjourney.js)
+[![nuget](https://img.shields.io/badge/nuget-v0.3.0-purple)](https://www.nuget.org/packages/jJourney.js/)
[![license](https://img.shields.io/badge/license-MIT-green)](https://github.com/williamtroup/Journey.js/blob/main/LICENSE.txt)
[![discussions Welcome](https://img.shields.io/badge/discussions-Welcome-red)](https://github.com/williamtroup/Journey.js/discussions)
[![coded by William Troup](https://img.shields.io/badge/coded_by-William_Troup-yellow)](https://github.com/williamtroup)
>
🚶 A lightweight, and easy-to-use, JavaScript library for building a website walk-through guide!
-> v0.2.1
+> v0.3.0
![Journey.js](docs/images/main.png)
@@ -24,6 +24,7 @@ Journey.js
- Fully styled in CSS/SASS and compatible with the Bootstrap library.
- Full CSS theme support (using :root variables, with a default dark-mode theme).
- Custom triggers for actions (when the dialog is shown for an element, or hidden, etc).
+- Shortcut keys (click [here](docs/SHORTCUT_KEYS.md) to see the full list).
diff --git a/README_NUGET.md b/README_NUGET.md
index 410f977..ca64f2d 100644
--- a/README_NUGET.md
+++ b/README_NUGET.md
@@ -1,8 +1,8 @@
-# Journey.js v0.2.1
+# Journey.js v0.3.0
[![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Journey.js%2C%20a%20free%20JavaScript%journey%builder&url=https://github.com/williamtroup/Journey.js&hashtags=javascript,html,journey,guide)
-[![npm](https://img.shields.io/badge/npmjs-v0.2.1-blue)](https://www.npmjs.com/package/jjourney.js)
-[![nuget](https://img.shields.io/badge/nuget-v0.2.1-purple)](https://www.nuget.org/packages/jJourney.js/)
+[![npm](https://img.shields.io/badge/npmjs-v0.3.0-blue)](https://www.npmjs.com/package/jjourney.js)
+[![nuget](https://img.shields.io/badge/nuget-v0.3.0-purple)](https://www.nuget.org/packages/jJourney.js/)
[![license](https://img.shields.io/badge/license-MIT-green)](https://github.com/williamtroup/Journey.js/blob/main/LICENSE.txt)
[![discussions Welcome](https://img.shields.io/badge/discussions-Welcome-red)](https://github.com/williamtroup/Journey.js/discussions)
[![coded by William Troup](https://img.shields.io/badge/coded_by-William_Troup-yellow)](https://github.com/williamtroup)
@@ -17,6 +17,7 @@
- Fully styled in CSS/SASS and compatible with the Bootstrap library.
- Full CSS theme support (using :root variables, with a default dark-mode theme).
- Custom triggers for actions (when the dialog is shown for an element, or hidden, etc).
+- Shortcut keys (click [here](https://github.com/williamtroup/Journey.js/blob/main/docs/SHORTCUT_KEYS.md) to see the full list).
## What browsers are supported?
diff --git a/dist/journey.js b/dist/journey.js
index 7b13dde..e37ce30 100644
--- a/dist/journey.js
+++ b/dist/journey.js
@@ -1,4 +1,4 @@
-/*! Journey.js v0.2.1 | (c) Bunoon | MIT License */
+/*! Journey.js v0.3.0 | (c) Bunoon | MIT License */
(function() {
function renderDisabledBackground() {
_element_Disabled_Background = createElement("div", "journey-js-disabled-background");
@@ -39,12 +39,11 @@
_element_Dialog.style.display = "none";
}
function onDialogPrevious() {
- removeFocusClassFromLastElement();
- _elements_Attributes_Position--;
- if (_elements_Attributes_Position < 0) {
- _elements_Attributes_Position = _elements_Attributes_Keys.length - 1;
+ if (_elements_Attributes_Position > 0) {
+ removeFocusClassFromLastElement();
+ _elements_Attributes_Position--;
+ showDialogAndSetPosition();
}
- showDialogAndSetPosition();
}
function onDialogNext() {
if (_elements_Attributes_Position === _elements_Attributes_Keys.length - 1) {
@@ -141,6 +140,7 @@
if (isDefinedNumber(bindingOptions.order) && (isDefinedString(bindingOptions.title) || isDefinedString(bindingOptions.description))) {
_elements_Attributes_Json[bindingOptions.order] = bindingOptions;
_elements_Attributes_Keys.push(bindingOptions.order);
+ element.removeAttribute(_attribute_Name_Journey);
}
} else {
if (!_configuration.safeMode) {
@@ -157,6 +157,27 @@
}
return result;
}
+ function buildDocumentEvents(addEvents) {
+ addEvents = isDefined(addEvents) ? addEvents : true;
+ var documentFunc = addEvents ? _parameter_Document.addEventListener : _parameter_Document.removeEventListener;
+ if (_configuration.shortcutKeysEnabled) {
+ documentFunc("keydown", onWindowKeyDown);
+ }
+ }
+ function onWindowKeyDown(e) {
+ if (_this.isOpen()) {
+ if (e.keyCode === _enum_KeyCodes.escape) {
+ e.preventDefault();
+ onDialogClose();
+ } else if (e.keyCode === _enum_KeyCodes.left) {
+ e.preventDefault();
+ onDialogPrevious();
+ } else if (e.keyCode === _enum_KeyCodes.right) {
+ e.preventDefault();
+ onDialogNext();
+ }
+ }
+ }
function buildAttributeOptions(newOptions) {
var options = !isDefinedObject(newOptions) ? {} : newOptions;
options.order = getDefaultNumber(options.order, 0);
@@ -312,11 +333,13 @@
_configuration.nextButtonText = getDefaultString(_configuration.nextButtonText, "Next");
_configuration.finishButtonText = getDefaultString(_configuration.finishButtonText, "Finish");
_configuration.showCloseButton = getDefaultBoolean(_configuration.showCloseButton, true);
+ _configuration.shortcutKeysEnabled = getDefaultBoolean(_configuration.shortcutKeysEnabled, true);
}
var _this = this;
var _parameter_Document = null;
var _parameter_Window = null;
var _configuration = {};
+ var _enum_KeyCodes = {escape:27, left:37, right:39};
var _string = {empty:"", space:" "};
var _elements_Type = {};
var _elements_Attributes_Json = {};
@@ -356,7 +379,7 @@
return _elements_Attributes_Position >= _elements_Attributes_Keys.length - 1;
};
this.getVersion = function() {
- return "0.2.1";
+ return "0.3.0";
};
(function(documentObject, windowObject) {
_parameter_Document = documentObject;
@@ -366,6 +389,7 @@
renderDisabledBackground();
renderDialog();
getElements();
+ buildDocumentEvents();
});
if (!isDefined(_parameter_Window.$journey)) {
_parameter_Window.$journey = this;
diff --git a/dist/journey.js.css b/dist/journey.js.css
index dc377ab..65f69b7 100644
--- a/dist/journey.js.css
+++ b/dist/journey.js.css
@@ -1,5 +1,5 @@
/*
- * Journey.js Library v0.2.1
+ * Journey.js Library v0.3.0
*
* Copyright 2023 Bunoon
* Released under the MIT License
@@ -22,10 +22,14 @@
--dialog-button-hover-background-color: #007FFF;
--dialog-button-hover-border-color: var(--dialog-button-border-color);
--dialog-button-hover-text-color: var(--dialog-button-text-color);
- --dialog-button-disabled-background-color: #002244;
- --dialog-close-button-color: var(--color-white);
- --dialog-close-button-hover-color: var(--dialog-button-hover-background-color);
+ --dialog-button-disabled-background-color: var(--dialog-background-color);
+ --dialog-close-button-background-color: var(--dialog-button-background-color);
+ --dialog-close-button-border-color: #3457D5;
--dialog-close-button-size: 1.1rem;
+ --dialog-close-button-x-color: var(--color-white);
+ --dialog-close-button-hover-background-color: #007FFF;
+ --dialog-close-button-hover-x-color: var(--dialog-close-button-x-color);
+ --dialog-close-button-hover-border-color: var(--dialog-close-button-border-color);
--border-radius: 0.5rem;
--border-size: 0.5px;
--spacing: 10px;
@@ -62,14 +66,14 @@ div.journey-js-dialog button.close {
height: var(--dialog-close-button-size);
border-radius: 0.25rem;
padding: 0;
- background-color: transparent;
- border: var(--border-size) solid var(--dialog-close-button-color);
+ background-color: var(--dialog-close-button-background-color);
+ border: var(--border-size) solid var(--dialog-close-button-border-color);
}
div.journey-js-dialog button.close::before, div.journey-js-dialog button.close::after {
content: "";
width: 1px;
height: 100%;
- background: var(--dialog-close-button-color);
+ background: var(--dialog-close-button-x-color);
display: block;
transform: rotate(45deg) translateX(0px);
position: absolute;
@@ -81,11 +85,12 @@ div.journey-js-dialog button.close::after {
}
div.journey-js-dialog button.close:hover {
cursor: pointer;
- border: var(--border-size) solid var(--dialog-close-button-hover-color);
+ border: var(--border-size) solid var(--dialog-close-button-hover-border-color);
transition: var(--transition);
+ background-color: var(--dialog-close-button-hover-background-color);
}
div.journey-js-dialog button.close:hover::before, div.journey-js-dialog button.close:hover::after {
- background: var(--dialog-close-button-hover-color);
+ background: var(--dialog-close-button-hover-x-color);
transition: var(--transition);
}
div.journey-js-dialog div:first-of-type {
diff --git a/dist/journey.js.css.map b/dist/journey.js.css.map
index 0765ee3..5597cc3 100644
--- a/dist/journey.js.css.map
+++ b/dist/journey.js.css.map
@@ -1 +1 @@
-{"version":3,"sourceRoot":"","sources":["../src/journey.js.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAAA;AAMA;EAEI;EACA;EACA;EAGA;EACA;EACA;EAGA;EACA;EACA;EAGA;EACA;EACA;EAGA;EAGA;EACA;EACA;EAGA;EACA;EAGA;EAGA;;;AAIJ;AAAA;AAAA;AAAA;AAAA;AAMA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;;AAGJ;EACI;EACA;EACA;;AAEA;EAEI;EACA;;AAMR;EACI;;AAIR;EACI;EACA;;AAGJ;EACI;;AAGJ;EACI;EACA;;AAEA;AAAA;EAEI;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACI;EACA;EACA;EACA;EACA;;AAGJ;AAAA;EACI;EACA;;AAIR;EACI;;;AAMZ;AAAA;AAAA;AAAA;AAAA;AAMA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI","file":"journey.js.css"}
\ No newline at end of file
+{"version":3,"sourceRoot":"","sources":["../src/journey.js.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAAA;AAMA;EAEI;EACA;EACA;EAGA;EACA;EACA;EAGA;EACA;EACA;EAGA;EACA;EACA;EAGA;EAGA;EACA;EACA;EACA;EAGA;EACA;EACA;EAGA;EACA;EAGA;EAGA;;;AAIJ;AAAA;AAAA;AAAA;AAAA;AAMA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;;AAGJ;EACI;EACA;EACA;EACA;;AAEA;EAEI;EACA;;AAMR;EACI;;AAIR;EACI;EACA;;AAGJ;EACI;;AAGJ;EACI;EACA;;AAEA;AAAA;EAEI;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACI;EACA;EACA;EACA;EACA;;AAGJ;AAAA;EACI;EACA;;AAIR;EACI;;;AAMZ;AAAA;AAAA;AAAA;AAAA;AAMA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI","file":"journey.js.css"}
\ No newline at end of file
diff --git a/dist/journey.js.min.css b/dist/journey.js.min.css
index 5f4e7db..61a3002 100644
--- a/dist/journey.js.min.css
+++ b/dist/journey.js.min.css
@@ -1,2 +1,2 @@
-/*! Journey.js v0.2.1 | (c) Bunoon | MIT License */
-:root{--color-black:#3b3a3a;--color-white:#F5F5F5;--color-gray:#AAA;--dialog-background-color:#024;--dialog-text-color:var(--color-white);--dialog-border-color:#72A0C1;--dialog-button-background-color:#002D62;--dialog-button-border-color:#3457D5;--dialog-button-text-color:var(--color-white);--dialog-button-hover-background-color:#007FFF;--dialog-button-hover-border-color:var(--dialog-button-border-color);--dialog-button-hover-text-color:var(--dialog-button-text-color);--dialog-button-disabled-background-color:#024;--dialog-close-button-color:var(--color-white);--dialog-close-button-hover-color:var(--dialog-button-hover-background-color);--dialog-close-button-size:1.1rem;--border-radius:.5rem;--border-size:.5px;--spacing:10px;--transition:all .3s}div.journey-js-dialog{position:absolute;display:none;border-radius:var(--border-radius);background-color:var(--dialog-background-color);color:var(--dialog-text-color);border:var(--border-size) solid var(--dialog-border-color);padding:var(--spacing);font-family:"Montserrat",sans-serif;font-size:.9rem;z-index:1001;width:300px;height:auto;-webkit-user-select:none;-ms-user-select:none;user-select:none}div.journey-js-dialog button.close{position:absolute;top:var(--spacing);right:var(--spacing);width:var(--dialog-close-button-size);height:var(--dialog-close-button-size);border-radius:.25rem;padding:0;background-color:transparent;border:var(--border-size) solid var(--dialog-close-button-color)}div.journey-js-dialog button.close::before,div.journey-js-dialog button.close::after{content:"";width:1px;height:100%;background:var(--dialog-close-button-color);display:block;transform:rotate(45deg) translateX(0);position:absolute;left:50%;top:0}div.journey-js-dialog button.close::after{transform:rotate(-45deg) translateX(0)}div.journey-js-dialog button.close:hover{cursor:pointer;border:var(--border-size) solid var(--dialog-close-button-hover-color);transition:var(--transition)}div.journey-js-dialog button.close:hover::before,div.journey-js-dialog button.close:hover::after{background:var(--dialog-close-button-hover-color);transition:var(--transition)}div.journey-js-dialog div:first-of-type{padding-right:calc(var(--dialog-close-button-size) + var(--spacing))}div.journey-js-dialog div.title{font-size:large;font-weight:700}div.journey-js-dialog div.description{font-weight:100}div.journey-js-dialog div.buttons{margin-top:var(--spacing);text-align:right}div.journey-js-dialog div.buttons button.previous,div.journey-js-dialog div.buttons button.next{border-radius:var(--border-radius);background-color:var(--dialog-button-background-color);color:var(--dialog-button-text-color);border:var(--border-size) solid var(--dialog-button-border-color);min-width:100px;padding:var(--spacing)}div.journey-js-dialog div.buttons button.previous:not([disabled]):hover,div.journey-js-dialog div.buttons button.next:not([disabled]):hover{cursor:pointer;background-color:var(--dialog-button-hover-background-color);color:var(--dialog-button-hover-text-color);border:var(--border-size) solid var(--dialog-button-hover-border-color);transition:var(--transition)}div.journey-js-dialog div.buttons button.previous:disabled,div.journey-js-dialog div.buttons button.next:disabled{background-color:var(--dialog-button-disabled-background-color)!important;color:var(--color-gray)}div.journey-js-dialog div.buttons button.next{font-weight:700}div.journey-js-disabled-background{z-index:1000;position:fixed;background-color:#000;background-color:rgba(0,0,0,.5);top:0;left:0;height:100%;width:100%}.journey-js-element-focus{z-index:1001!important}
\ No newline at end of file
+/*! Journey.js v0.3.0 | (c) Bunoon | MIT License */
+:root{--color-black:#3b3a3a;--color-white:#F5F5F5;--color-gray:#AAA;--dialog-background-color:#024;--dialog-text-color:var(--color-white);--dialog-border-color:#72A0C1;--dialog-button-background-color:#002D62;--dialog-button-border-color:#3457D5;--dialog-button-text-color:var(--color-white);--dialog-button-hover-background-color:#007FFF;--dialog-button-hover-border-color:var(--dialog-button-border-color);--dialog-button-hover-text-color:var(--dialog-button-text-color);--dialog-button-disabled-background-color:var(--dialog-background-color);--dialog-close-button-background-color:var(--dialog-button-background-color);--dialog-close-button-border-color:#3457D5;--dialog-close-button-size:1.1rem;--dialog-close-button-x-color:var(--color-white);--dialog-close-button-hover-background-color:#007FFF;--dialog-close-button-hover-x-color:var(--dialog-close-button-x-color);--dialog-close-button-hover-border-color:var(--dialog-close-button-border-color);--border-radius:.5rem;--border-size:.5px;--spacing:10px;--transition:all .3s}div.journey-js-dialog{position:absolute;display:none;border-radius:var(--border-radius);background-color:var(--dialog-background-color);color:var(--dialog-text-color);border:var(--border-size) solid var(--dialog-border-color);padding:var(--spacing);font-family:"Montserrat",sans-serif;font-size:.9rem;z-index:1001;width:300px;height:auto;-webkit-user-select:none;-ms-user-select:none;user-select:none}div.journey-js-dialog button.close{position:absolute;top:var(--spacing);right:var(--spacing);width:var(--dialog-close-button-size);height:var(--dialog-close-button-size);border-radius:.25rem;padding:0;background-color:var(--dialog-close-button-background-color);border:var(--border-size) solid var(--dialog-close-button-border-color)}div.journey-js-dialog button.close::before,div.journey-js-dialog button.close::after{content:"";width:1px;height:100%;background:var(--dialog-close-button-x-color);display:block;transform:rotate(45deg) translateX(0);position:absolute;left:50%;top:0}div.journey-js-dialog button.close::after{transform:rotate(-45deg) translateX(0)}div.journey-js-dialog button.close:hover{cursor:pointer;border:var(--border-size) solid var(--dialog-close-button-hover-border-color);transition:var(--transition);background-color:var(--dialog-close-button-hover-background-color)}div.journey-js-dialog button.close:hover::before,div.journey-js-dialog button.close:hover::after{background:var(--dialog-close-button-hover-x-color);transition:var(--transition)}div.journey-js-dialog div:first-of-type{padding-right:calc(var(--dialog-close-button-size) + var(--spacing))}div.journey-js-dialog div.title{font-size:large;font-weight:700}div.journey-js-dialog div.description{font-weight:100}div.journey-js-dialog div.buttons{margin-top:var(--spacing);text-align:right}div.journey-js-dialog div.buttons button.previous,div.journey-js-dialog div.buttons button.next{border-radius:var(--border-radius);background-color:var(--dialog-button-background-color);color:var(--dialog-button-text-color);border:var(--border-size) solid var(--dialog-button-border-color);min-width:100px;padding:var(--spacing)}div.journey-js-dialog div.buttons button.previous:not([disabled]):hover,div.journey-js-dialog div.buttons button.next:not([disabled]):hover{cursor:pointer;background-color:var(--dialog-button-hover-background-color);color:var(--dialog-button-hover-text-color);border:var(--border-size) solid var(--dialog-button-hover-border-color);transition:var(--transition)}div.journey-js-dialog div.buttons button.previous:disabled,div.journey-js-dialog div.buttons button.next:disabled{background-color:var(--dialog-button-disabled-background-color)!important;color:var(--color-gray)}div.journey-js-dialog div.buttons button.next{font-weight:700}div.journey-js-disabled-background{z-index:1000;position:fixed;background-color:#000;background-color:rgba(0,0,0,.5);top:0;left:0;height:100%;width:100%}.journey-js-element-focus{z-index:1001!important}
\ No newline at end of file
diff --git a/dist/journey.min.js b/dist/journey.min.js
index 37884c8..047f2f1 100644
--- a/dist/journey.min.js
+++ b/dist/journey.min.js
@@ -1,11 +1,12 @@
-/*! Journey.js v0.2.1 | (c) Bunoon | MIT License */
-(function(){function x(){var a=y[m[k]];l(a.element)&&G(a.onClose,a.element);H(!1);a=n.body;var c=I;try{a.contains(c)&&a.removeChild(c)}catch(b){console.warn(b.message)}g.style.display="none"}function T(){H();k--;0>k&&(k=m.length-1);J()}function U(){k===m.length-1?x():(H(),k++,J())}function J(){var a=y[m[k]];if(l(a)&&l(a.element)){var c=n.body,b=I;try{c.contains(b)||c.appendChild(b)}catch(u){console.warn(u.message)}z.style.display=f.showCloseButton?"block":"none";a.element.className+=p.space+"journey-js-element-focus";
-var e=a.element;for(b=c=0;e&&!isNaN(e.offsetLeft)&&!isNaN(e.offsetTop);)c+=e.offsetLeft-e.scrollLeft,b+=e.offsetTop-e.scrollTop,e=e.offsetParent;var h=n.documentElement;e=(q.pageXOffset||h.scrollLeft)-(h.clientLeft||0);h=(q.pageYOffset||h.scrollTop)-(h.clientTop||0);b=b-h+a.element.offsetHeight;c-=e;e=a.element;h=null;q.getComputedStyle?h=document.defaultView.getComputedStyle(e,null).getPropertyValue("position"):e.currentStyle&&(h=e.currentStyle.position);e=h;e!==p.empty&&"static"===e.toLowerCase()&&
-(K=e,a.element.style.position="relative");v.innerHTML=f.previousButtonText;v.disabled=0===k;A.innerHTML=k>=m.length-1?f.finishButtonText:f.nextButtonText;r(a.title)?B.innerHTML=a.title:B.innerHTML=p.empty;r(a.description)?C.innerHTML=a.description:C.innerHTML=p.empty;g.style.display="block";c+g.offsetWidth>q.innerWidth&&(c-=g.offsetWidth+a.element.offsetWidth);b+g.offsetHeight>q.innerHeight&&(b-=g.offsetHeight+a.element.offsetHeight);g.style.top=b+"px";g.style.left=c+"px";G(a.onEnter,a.element)}}
-function H(a){a=l(a)?a:!0;var c=y[m[k]];l(c.element)&&(c.element.className=c.element.className.replace(p.space+"journey-js-element-focus",p.empty),l(K)&&(c.element.style.position=K),a&&G(c.onLeave,c.element))}function l(a){return null!==a&&void 0!==a&&a!==p.empty}function D(a){return l(a)&&"object"===typeof a}function Q(a){return l(a)&&"boolean"===typeof a}function r(a){return l(a)&&"string"===typeof a}function L(a){return l(a)&&"function"===typeof a}function R(a){return l(a)&&"number"===typeof a}
-function t(a,c){var b=a.toLowerCase();var e="text"===b;M.hasOwnProperty(b)||(M[b]=e?n.createTextNode(p.empty):n.createElement(b));b=M[b].cloneNode(!1);l(c)&&(b.className=c);return b}function G(a){L(a)&&a.apply(null,[].slice.call(arguments,1))}function w(a,c){return r(a)?a:c}function N(a,c){return L(a)?a:c}function V(a){var c=!0,b=null;try{r(a)&&(b=JSON.parse(a))}catch(e){try{b=eval("("+a+")"),L(b)&&(b=b())}catch(h){f.safeMode||(console.error("Errors in object: "+e.message+", "+h.message),c=!1),b=
-null}}return{parsed:c,result:b}}function S(){var a=f;var c=f.safeMode;c=Q(c)?c:!0;a.safeMode=c;a=f;var b=f.domElementTypes;c=["*"];r(b)?(b=b.split(p.space),0===b.length&&(b=c)):b=D(b)&&b instanceof Array?b:c;a.domElementTypes=b;f.previousButtonText=w(f.previousButtonText,"Previous");f.nextButtonText=w(f.nextButtonText,"Next");f.finishButtonText=w(f.finishButtonText,"Finish");a=f;c=f.showCloseButton;c=Q(c)?c:!0;a.showCloseButton=c}var W=this,n=null,q=null,f={},p={empty:"",space:" "},M={},y={},m=[],
-k=0,K=null,I=null,g=null,z=null,B=null,C=null,v=null,A=null;this.setConfiguration=function(a){f=D(a)?a:{};S();W.isOpen()&&(x(),k=0);return this};this.show=function(){k===m.length-1&&(k=0);J()};this.hide=function(){x()};this.isOpen=function(){return"block"===g.style.display};this.isComplete=function(){return k>=m.length-1};this.getVersion=function(){return"0.2.1"};(function(a,c){n=a;q=c;S();n.addEventListener("DOMContentLoaded",function(){I=t("div","journey-js-disabled-background");g=t("div","journey-js-dialog");
-g.style.display="none";n.body.appendChild(g);z=t("button","close");z.onclick=x;g.appendChild(z);B=t("div","title");g.appendChild(B);C=t("div","description");g.appendChild(C);var b=t("div","buttons");g.appendChild(b);v=t("button","previous");v.onclick=T;b.appendChild(v);A=t("button","next");A.onclick=U;b.appendChild(A);b=f.domElementTypes;for(var e=b.length,h=0;h=n.length-1?f.finishButtonText:f.nextButtonText;r(a.title)?C.innerHTML=a.title:C.innerHTML=p.empty;r(a.description)?D.innerHTML=a.description:D.innerHTML=p.empty;g.style.display="block";c+g.offsetWidth>q.innerWidth&&(c-=g.offsetWidth+a.element.offsetWidth);b+g.offsetHeight>q.innerHeight&&(b-=g.offsetHeight+a.element.offsetHeight);g.style.top=b+"px";g.style.left=c+"px";G(a.onEnter,a.element)}}
+function H(a){a=k(a)?a:!0;var c=z[n[l]];k(c.element)&&(c.element.className=c.element.className.replace(p.space+"journey-js-element-focus",p.empty),k(K)&&(c.element.style.position=K),a&&G(c.onLeave,c.element))}function X(a){U.isOpen()&&(a.keyCode===L.escape?(a.preventDefault(),v()):a.keyCode===L.left?(a.preventDefault(),S()):a.keyCode===L.right&&(a.preventDefault(),T()))}function k(a){return null!==a&&void 0!==a&&a!==p.empty}function E(a){return k(a)&&"object"===typeof a}function r(a){return k(a)&&
+"string"===typeof a}function M(a){return k(a)&&"function"===typeof a}function V(a){return k(a)&&"number"===typeof a}function t(a,c){var b=a.toLowerCase();var e="text"===b;N.hasOwnProperty(b)||(N[b]=e?m.createTextNode(p.empty):m.createElement(b));b=N[b].cloneNode(!1);k(c)&&(b.className=c);return b}function G(a){M(a)&&a.apply(null,[].slice.call(arguments,1))}function x(a,c){return r(a)?a:c}function O(a,c){return k(a)&&"boolean"===typeof a?a:c}function P(a,c){return M(a)?a:c}function Y(a){var c=!0,b=
+null;try{r(a)&&(b=JSON.parse(a))}catch(e){try{b=eval("("+a+")"),M(b)&&(b=b())}catch(h){f.safeMode||(console.error("Errors in object: "+e.message+", "+h.message),c=!1),b=null}}return{parsed:c,result:b}}function W(){f.safeMode=O(f.safeMode,!0);var a=f,c=f.domElementTypes,b=["*"];r(c)?(c=c.split(p.space),0===c.length&&(c=b)):c=E(c)&&c instanceof Array?c:b;a.domElementTypes=c;f.previousButtonText=x(f.previousButtonText,"Previous");f.nextButtonText=x(f.nextButtonText,"Next");f.finishButtonText=x(f.finishButtonText,
+"Finish");f.showCloseButton=O(f.showCloseButton,!0);f.shortcutKeysEnabled=O(f.shortcutKeysEnabled,!0)}var U=this,m=null,q=null,f={},L={escape:27,left:37,right:39},p={empty:"",space:" "},N={},z={},n=[],l=0,K=null,I=null,g=null,A=null,C=null,D=null,w=null,B=null;this.setConfiguration=function(a){f=E(a)?a:{};W();U.isOpen()&&(v(),l=0);return this};this.show=function(){l===n.length-1&&(l=0);J()};this.hide=function(){v()};this.isOpen=function(){return"block"===g.style.display};this.isComplete=function(){return l>=
+n.length-1};this.getVersion=function(){return"0.3.0"};(function(a,c){m=a;q=c;W();m.addEventListener("DOMContentLoaded",function(){I=t("div","journey-js-disabled-background");g=t("div","journey-js-dialog");g.style.display="none";m.body.appendChild(g);A=t("button","close");A.onclick=v;g.appendChild(A);C=t("div","title");g.appendChild(C);D=t("div","description");g.appendChild(D);var b=t("div","buttons");g.appendChild(b);w=t("button","previous");w.onclick=S;b.appendChild(w);B=t("button","next");B.onclick=
+T;b.appendChild(B);b=f.domElementTypes;for(var e=b.length,h=0;h
| Type: | Name: | Description: |
@@ -12,7 +12,7 @@ Below are all the JSON properties that can be passed in the "data-journey-option
-### Translatable String Options:
+## Translatable String Options:
| Type: | Name: | Description: |
diff --git a/docs/BINDING_OPTIONS_CUSTOM_TRIGGERS.md b/docs/BINDING_OPTIONS_CUSTOM_TRIGGERS.md
index 8132c7d..cc85df7 100644
--- a/docs/BINDING_OPTIONS_CUSTOM_TRIGGERS.md
+++ b/docs/BINDING_OPTIONS_CUSTOM_TRIGGERS.md
@@ -5,7 +5,7 @@ Below is a list of all the custom triggers supported in the "data-journey-option
-For Viewing:
+## For Viewing:
### options.onEnter( *element* ):
Fires when the the dialog is shown for a specific DOM element.
diff --git a/docs/CHANGE_LOG.md b/docs/CHANGE_LOG.md
index 53af95c..06d012a 100644
--- a/docs/CHANGE_LOG.md
+++ b/docs/CHANGE_LOG.md
@@ -1,5 +1,28 @@
# Journey.js - Change Log:
+## Version 0.3.0:
+
+#### **New Features:**
+- Added shortcut keys "Left", "Right", and "Escape", which move to the previous/next element in the journey, and close the dialog.
+
+#### **Configuration Options:**
+- Added a new configuration option "shortcutKeysEnabled" (defaults to true), which states if the shortcut keys (for navigation) are enabled.
+
+#### **CSS:**
+- Added CSS ":root" variable "--dialog-close-button-background-color", which states the background color to use for the close button.
+- Added CSS ":root" variable "--dialog-close-button-border-color", which states the border color to use for the close button.
+- Added CSS ":root" variable "--dialog-close-button-hover-background-color", which states the background color to use for the close button when hovered.
+- Renamed one or two of the other ":root" variables for the Close button.
+
+#### **General Improvements:**
+- The attribute "data-journey-options" is now removed from all elements after they are processed.
+
+#### **Fixes:**
+- Fixed the previous buttons event sometimes allowing a loop back to the end.
+
+
+
+
## Version 0.2.1:
- Added Code of Conduct, Contributing, and Security Policy.
diff --git a/docs/CONFIGURATION_OPTIONS.md b/docs/CONFIGURATION_OPTIONS.md
index 23d0878..3d12e8b 100644
--- a/docs/CONFIGURATION_OPTIONS.md
+++ b/docs/CONFIGURATION_OPTIONS.md
@@ -1,11 +1,10 @@
# Journey.js - Configuration Options:
Below are all the configuration options that can be passed to the "setConfiguration()" public function.
+
+
-### Options:
-
-
| Type: | Name: | Description: |
| --- | --- | --- |
| *boolean* | safeMode | States if safe-mode is enabled (errors will be ignored and logged only (defaults to true). |
@@ -13,4 +12,5 @@ Below are all the configuration options that can be passed to the "setConfigurat
| *string* | previousButtonText | States the text that should be used for the Previous button (defaults to "Previous"). |
| *string* | nextButtonText | States the text that should be used for the Next button (defaults to "Next"). |
| *string* | finishButtonText | States the text that should be used for the Finish button (defaults to "Finish"). |
-| *boolean* | showCloseButton | States if the Close button is visible on the dialog (defaults to true). |
\ No newline at end of file
+| *boolean* | showCloseButton | States if the Close button is visible on the dialog (defaults to true). |
+| *boolean* | shortcutKeysEnabled | States if the shortcut keys are enabled (defaults to true). |
\ No newline at end of file
diff --git a/docs/PUBLIC_FUNCTIONS.md b/docs/PUBLIC_FUNCTIONS.md
index 55e302e..0973813 100644
--- a/docs/PUBLIC_FUNCTIONS.md
+++ b/docs/PUBLIC_FUNCTIONS.md
@@ -5,7 +5,7 @@ Below is a list of all the public functions that can be called from the Journey.
-Show/Hide:
+## Show/Hide:
### **show()**:
Shows the Journey.js dialog for the element in the last known position (defaults to the start).
@@ -26,10 +26,10 @@ Returns a flag that states if the dialog is opened.
Returns a flag that states if the full journey has been completed.
***Returns***: '*boolean*' - The flag that states if the full journey has been completed.
+
-
-Configuration:
+## Configuration:
### **setConfiguration( *newOptions* )**:
Sets the specific configuration options that should be used.
@@ -37,10 +37,10 @@ Sets the specific configuration options that should be used.
***Parameter: newOptions***: '*Options*' - All the configuration options that should be set (refer to ["Configuration Options"](CONFIGURATION_OPTIONS.md) documentation for properties).
***Returns***: '*Object*' - The Journey.js class instance.
+
-
-Additional Data:
+## Additional Data:
### **getVersion()**:
Returns the version of Journey.js.
diff --git a/docs/SHORTCUT_KEYS.md b/docs/SHORTCUT_KEYS.md
new file mode 100644
index 0000000..fc7698c
--- /dev/null
+++ b/docs/SHORTCUT_KEYS.md
@@ -0,0 +1,12 @@
+# Journey.js - Shortcut Keys:
+
+Below is a list of all the shortcut keys supported in Journey.js.
+
+
+
+
+| Key: | Description: |
+| --- | --- |
+| *Left* | Moves to the previous element in the journey. |
+| *Right* | Moves to the next element in the journey. |
+| *Escape* | Close the dialog. |
\ No newline at end of file
diff --git a/docs/images/main.png b/docs/images/main.png
index 6ee334d..78dcff8 100644
Binary files a/docs/images/main.png and b/docs/images/main.png differ
diff --git a/journey.js.nuspec b/journey.js.nuspec
index 9cb56fb..e002a87 100644
--- a/journey.js.nuspec
+++ b/journey.js.nuspec
@@ -2,7 +2,7 @@
jJourney.js
- 0.2.1
+ 0.3.0
Journey.js
A lightweight, and easy-to-use, JavaScript library for building a website walk-through guide!
William Troup
diff --git a/package.json b/package.json
index 6388e1c..2ad279a 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "jjourney.js",
"title": "Journey.js",
"description": "A lightweight, and easy-to-use, JavaScript library for building a website walk-through guide!",
- "version": "0.2.1",
+ "version": "0.3.0",
"main": "dist/journey.js",
"author": {
"name": "Bunoon"
diff --git a/src/journey.js b/src/journey.js
index a9fa6ec..e88be39 100644
--- a/src/journey.js
+++ b/src/journey.js
@@ -4,7 +4,7 @@
* A lightweight, and easy-to-use, JavaScript library for building a website walk-through guide!
*
* @file journey.js
- * @version v0.2.1
+ * @version v0.3.0
* @author Bunoon
* @license MIT License
* @copyright Bunoon 2023
@@ -21,6 +21,13 @@
// Variables: Configuration
_configuration = {},
+ // Variables: Enums
+ _enum_KeyCodes = {
+ escape: 27,
+ left: 37,
+ right: 39
+ },
+
// Variables: Strings
_string = {
empty: "",
@@ -117,15 +124,13 @@
}
function onDialogPrevious() {
- removeFocusClassFromLastElement();
+ if ( _elements_Attributes_Position > 0 ) {
+ removeFocusClassFromLastElement();
- _elements_Attributes_Position--;
+ _elements_Attributes_Position--;
- if ( _elements_Attributes_Position < 0 ) {
- _elements_Attributes_Position = _elements_Attributes_Keys.length - 1;
- }
-
- showDialogAndSetPosition();
+ showDialogAndSetPosition();
+ }
}
function onDialogNext() {
@@ -259,6 +264,8 @@
if ( isDefinedNumber( bindingOptions.order ) && ( isDefinedString( bindingOptions.title ) || isDefinedString( bindingOptions.description ) ) ) {
_elements_Attributes_Json[ bindingOptions.order ] = bindingOptions;
_elements_Attributes_Keys.push( bindingOptions.order );
+
+ element.removeAttribute( _attribute_Name_Journey );
}
} else {
@@ -280,6 +287,40 @@
}
+ /*
+ * ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ * Document Events
+ * ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ */
+
+ function buildDocumentEvents( addEvents ) {
+ addEvents = isDefined( addEvents ) ? addEvents : true;
+
+ var documentFunc = addEvents ? _parameter_Document.addEventListener : _parameter_Document.removeEventListener;
+
+ if ( _configuration.shortcutKeysEnabled ) {
+ documentFunc( "keydown", onWindowKeyDown );
+ }
+ }
+
+ function onWindowKeyDown( e ) {
+ if ( _this.isOpen() ) {
+ if ( e.keyCode === _enum_KeyCodes.escape ) {
+ e.preventDefault();
+ onDialogClose();
+
+ } else if ( e.keyCode === _enum_KeyCodes.left ) {
+ e.preventDefault();
+ onDialogPrevious();
+
+ } else if ( e.keyCode === _enum_KeyCodes.right ) {
+ e.preventDefault();
+ onDialogNext();
+ }
+ }
+ }
+
+
/*
* ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Options
@@ -559,6 +600,7 @@
_configuration.nextButtonText = getDefaultString( _configuration.nextButtonText, "Next" );
_configuration.finishButtonText = getDefaultString( _configuration.finishButtonText, "Finish" );
_configuration.showCloseButton = getDefaultBoolean( _configuration.showCloseButton, true );
+ _configuration.shortcutKeysEnabled = getDefaultBoolean( _configuration.shortcutKeysEnabled, true );
}
@@ -637,7 +679,7 @@
* @returns {string} The version number.
*/
this.getVersion = function() {
- return "0.2.1";
+ return "0.3.0";
};
@@ -657,6 +699,7 @@
renderDisabledBackground();
renderDialog();
getElements();
+ buildDocumentEvents();
} );
if ( !isDefined( _parameter_Window.$journey ) ) {
diff --git a/src/journey.js.scss b/src/journey.js.scss
index 0e256be..f25b686 100644
--- a/src/journey.js.scss
+++ b/src/journey.js.scss
@@ -1,5 +1,5 @@
/*
- * Journey.js Library v0.2.1
+ * Journey.js Library v0.3.0
*
* Copyright 2023 Bunoon
* Released under the MIT License
@@ -34,13 +34,19 @@
--dialog-button-hover-text-color: var(--dialog-button-text-color);
// Dialog - Buttons - Disabled
- --dialog-button-disabled-background-color: #002244;
+ --dialog-button-disabled-background-color: var(--dialog-background-color);
// Dialog - Close Button
- --dialog-close-button-color: var(--color-white);
- --dialog-close-button-hover-color: var(--dialog-button-hover-background-color);
+ --dialog-close-button-background-color: var(--dialog-button-background-color);
+ --dialog-close-button-border-color: #3457D5;
--dialog-close-button-size: 1.1rem;
-
+ --dialog-close-button-x-color: var(--color-white);
+
+ // Dialog - Close Button - Hover
+ --dialog-close-button-hover-background-color: #007FFF;
+ --dialog-close-button-hover-x-color: var(--dialog-close-button-x-color);
+ --dialog-close-button-hover-border-color: var(--dialog-close-button-border-color);
+
// Borders
--border-radius: 0.5rem;
--border-size: 0.5px;
@@ -84,15 +90,15 @@ div.journey-js-dialog {
height: var(--dialog-close-button-size);
border-radius: 0.25rem;
padding: 0;
- background-color: transparent;
- border: var(--border-size) solid var(--dialog-close-button-color);
+ background-color: var(--dialog-close-button-background-color);
+ border: var(--border-size) solid var(--dialog-close-button-border-color);
&::before,
&::after {
content: '';
width: 1px;
height: 100%;
- background: var(--dialog-close-button-color);
+ background: var(--dialog-close-button-x-color);
display: block;
transform: rotate(45deg) translateX(0px);
position: absolute;
@@ -106,12 +112,13 @@ div.journey-js-dialog {
&:hover {
cursor: pointer;
- border: var(--border-size) solid var(--dialog-close-button-hover-color);
+ border: var(--border-size) solid var(--dialog-close-button-hover-border-color);
transition: var(--transition);
+ background-color: var(--dialog-close-button-hover-background-color);
&::before,
&::after {
- background: var(--dialog-close-button-hover-color);
+ background: var(--dialog-close-button-hover-x-color);
transition: var(--transition);
}
}