Add popover functionality
Browse files- .eslintrc.json +1 -0
- assets/scripts/src/element.js +33 -2
- assets/scripts/src/overlay.js +10 -0
- assets/scripts/src/sholo.js +9 -1
- assets/styles/scss/demo.scss +1 -7
- index.html +12 -8
.eslintrc.json
CHANGED
|
@@ -10,6 +10,7 @@
|
|
| 10 |
"no-cond-assign": "off",
|
| 11 |
"func-names": "off",
|
| 12 |
"no-bitwise": "off",
|
|
|
|
| 13 |
"no-param-reassign": [
|
| 14 |
"off"
|
| 15 |
],
|
|
|
|
| 10 |
"no-cond-assign": "off",
|
| 11 |
"func-names": "off",
|
| 12 |
"no-bitwise": "off",
|
| 13 |
+
"class-methods-use-this": "off",
|
| 14 |
"no-param-reassign": [
|
| 15 |
"off"
|
| 16 |
],
|
assets/scripts/src/element.js
CHANGED
|
@@ -11,6 +11,7 @@ export default class Element {
|
|
| 11 |
this.document = document;
|
| 12 |
this.window = window;
|
| 13 |
this.options = options;
|
|
|
|
| 14 |
}
|
| 15 |
|
| 16 |
/**
|
|
@@ -58,8 +59,38 @@ export default class Element {
|
|
| 58 |
return position;
|
| 59 |
}
|
| 60 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
onHighlighted() {
|
| 62 |
-
|
| 63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
}
|
| 65 |
}
|
|
|
|
| 11 |
this.document = document;
|
| 12 |
this.window = window;
|
| 13 |
this.options = options;
|
| 14 |
+
this.popover = this.getPopover();
|
| 15 |
}
|
| 16 |
|
| 17 |
/**
|
|
|
|
| 59 |
return position;
|
| 60 |
}
|
| 61 |
|
| 62 |
+
onDeselected() {
|
| 63 |
+
// Will be called when element is about to be deselected
|
| 64 |
+
this.hidePopover();
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
onHighlightStarted() {
|
| 68 |
+
// Will be triggered when the element is about to be highlighted
|
| 69 |
+
// i.e. overlay has started transitioning towards this element
|
| 70 |
+
this.showPopover();
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
onHighlighted() {
|
| 74 |
+
this.showPopover();
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
showPopover() {
|
| 78 |
+
const position = this.getCalculatedPosition();
|
| 79 |
+
|
| 80 |
+
this.popover.style.left = `${position.left}px`;
|
| 81 |
+
this.popover.style.top = `${position.bottom + 10}px`;
|
| 82 |
+
this.popover.style.display = 'block';
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
getPopover() {
|
| 86 |
+
// @todo: Create if not there
|
| 87 |
+
const popover = this.document.getElementById('sholo-popover-item');
|
| 88 |
+
popover.style.position = 'absolute';
|
| 89 |
+
|
| 90 |
+
return popover;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
hidePopover() {
|
| 94 |
+
this.popover.style.display = 'none';
|
| 95 |
}
|
| 96 |
}
|
assets/scripts/src/overlay.js
CHANGED
|
@@ -61,6 +61,14 @@ export default class Overlay {
|
|
| 61 |
return;
|
| 62 |
}
|
| 63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
// get the position of element around which we need to draw
|
| 65 |
const position = element.getCalculatedPosition();
|
| 66 |
if (!position.canHighlight()) {
|
|
@@ -92,6 +100,7 @@ export default class Overlay {
|
|
| 92 |
*/
|
| 93 |
clear() {
|
| 94 |
this.positionToHighlight = new Position();
|
|
|
|
| 95 |
this.highlightedElement = null;
|
| 96 |
|
| 97 |
this.draw();
|
|
@@ -245,6 +254,7 @@ export default class Overlay {
|
|
| 245 |
if (this.highlightedElement) {
|
| 246 |
this.window.cancelAnimationFrame(this.redrawAnimation);
|
| 247 |
this.highlight(this.highlightedElement, animate);
|
|
|
|
| 248 |
}
|
| 249 |
}
|
| 250 |
}
|
|
|
|
| 61 |
return;
|
| 62 |
}
|
| 63 |
|
| 64 |
+
// Trigger the hook for highlight started
|
| 65 |
+
element.onHighlightStarted();
|
| 66 |
+
|
| 67 |
+
// Old element has been deselected
|
| 68 |
+
if (this.highlightedElement) {
|
| 69 |
+
this.highlightedElement.onDeselected();
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
// get the position of element around which we need to draw
|
| 73 |
const position = element.getCalculatedPosition();
|
| 74 |
if (!position.canHighlight()) {
|
|
|
|
| 100 |
*/
|
| 101 |
clear() {
|
| 102 |
this.positionToHighlight = new Position();
|
| 103 |
+
this.highlightedElement.onDeselected();
|
| 104 |
this.highlightedElement = null;
|
| 105 |
|
| 106 |
this.draw();
|
|
|
|
| 254 |
if (this.highlightedElement) {
|
| 255 |
this.window.cancelAnimationFrame(this.redrawAnimation);
|
| 256 |
this.highlight(this.highlightedElement, animate);
|
| 257 |
+
this.highlightedElement.onHighlighted();
|
| 258 |
}
|
| 259 |
}
|
| 260 |
}
|
assets/scripts/src/sholo.js
CHANGED
|
@@ -42,6 +42,11 @@ export default class Sholo {
|
|
| 42 |
this.window.addEventListener('mouseup', this.onMouseUp, false);
|
| 43 |
}
|
| 44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
onMouseUp(e) {
|
| 46 |
const highlightedElement = this.overlay.getHighlightedElement();
|
| 47 |
const popover = document.getElementById('sholo-popover-item');
|
|
@@ -50,8 +55,11 @@ export default class Sholo {
|
|
| 50 |
return;
|
| 51 |
}
|
| 52 |
|
|
|
|
|
|
|
|
|
|
| 53 |
// Remove the overlay If clicked outside the highlighted element
|
| 54 |
-
if (!
|
| 55 |
this.overlay.clear();
|
| 56 |
}
|
| 57 |
}
|
|
|
|
| 42 |
this.window.addEventListener('mouseup', this.onMouseUp, false);
|
| 43 |
}
|
| 44 |
|
| 45 |
+
/**
|
| 46 |
+
* Removes the popover if clicked outside the highlighted element
|
| 47 |
+
* or outside the
|
| 48 |
+
* @param e
|
| 49 |
+
*/
|
| 50 |
onMouseUp(e) {
|
| 51 |
const highlightedElement = this.overlay.getHighlightedElement();
|
| 52 |
const popover = document.getElementById('sholo-popover-item');
|
|
|
|
| 55 |
return;
|
| 56 |
}
|
| 57 |
|
| 58 |
+
const clickedHighlightedElement = highlightedElement.node.contains(e.target);
|
| 59 |
+
const clickedPopover = popover && popover.contains(e.target);
|
| 60 |
+
|
| 61 |
// Remove the overlay If clicked outside the highlighted element
|
| 62 |
+
if (!clickedHighlightedElement && !clickedPopover) {
|
| 63 |
this.overlay.clear();
|
| 64 |
}
|
| 65 |
}
|
assets/styles/scss/demo.scss
CHANGED
|
@@ -48,13 +48,7 @@ section {
|
|
| 48 |
/////////////////////////////////////////
|
| 49 |
div#sholo-popover-item {
|
| 50 |
|
| 51 |
-
|
| 52 |
-
position: absolute;
|
| 53 |
-
top: 285px;
|
| 54 |
-
left: 710px;
|
| 55 |
-
//////////////////
|
| 56 |
-
|
| 57 |
-
display: block;
|
| 58 |
background: white;
|
| 59 |
margin: 0;
|
| 60 |
padding: 15px;
|
|
|
|
| 48 |
/////////////////////////////////////////
|
| 49 |
div#sholo-popover-item {
|
| 50 |
|
| 51 |
+
display: none;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
background: white;
|
| 53 |
margin: 0;
|
| 54 |
padding: 15px;
|
index.html
CHANGED
|
@@ -19,8 +19,8 @@
|
|
| 19 |
<h1>Sholo</h1>
|
| 20 |
<p class="text-muted">A light-weight, no-dependency, vanilla JavaScript library to bring certain parts of page in
|
| 21 |
spotlight</p>
|
| 22 |
-
<a href="
|
| 23 |
-
<a href="
|
| 24 |
</section>
|
| 25 |
<section class="section__purpose">
|
| 26 |
<h1>Whats does it do?</h1>
|
|
@@ -62,12 +62,16 @@
|
|
| 62 |
|
| 63 |
<script src="./assets/scripts/dist/sholo.js"></script>
|
| 64 |
<script>
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
</script>
|
| 72 |
</body>
|
| 73 |
</html>
|
|
|
|
| 19 |
<h1>Sholo</h1>
|
| 20 |
<p class="text-muted">A light-weight, no-dependency, vanilla JavaScript library to bring certain parts of page in
|
| 21 |
spotlight</p>
|
| 22 |
+
<a href="javascript:void(0)" class="btn btn__example btn__dark">Show an Example</a>
|
| 23 |
+
<a href="javascript:void(0)" class="btn btn__light">Learn More</a>
|
| 24 |
</section>
|
| 25 |
<section class="section__purpose">
|
| 26 |
<h1>Whats does it do?</h1>
|
|
|
|
| 62 |
|
| 63 |
<script src="./assets/scripts/dist/sholo.js"></script>
|
| 64 |
<script>
|
| 65 |
+
const sholo = new Sholo({
|
| 66 |
+
animate: true,
|
| 67 |
+
opacity: 0.8,
|
| 68 |
+
padding: 0
|
| 69 |
+
});
|
| 70 |
+
|
| 71 |
+
document.querySelector('.btn__example')
|
| 72 |
+
.addEventListener('click', function () {
|
| 73 |
+
sholo.highlight('.section__header');
|
| 74 |
+
});
|
| 75 |
</script>
|
| 76 |
</body>
|
| 77 |
</html>
|