Adding hover box element

This commit is contained in:
Shan Carter
2017-10-24 13:59:48 -07:00
parent 4c9c387760
commit 94bba88924
7 changed files with 159 additions and 156 deletions
+2 -1
View File
@@ -2,7 +2,8 @@
<head>
<script src="../dist/template.v2.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1" >
<meta charset="utf8">
</head>
<body>
+2 -1
View File
@@ -16,6 +16,7 @@ import { Code } from './components/d-code';
import { Footnote } from './components/d-footnote';
import { FootnoteList } from './components/d-footnote-list';
import { FrontMatter } from './components/d-front-matter';
import { HoverBox } from './components/d-hover-box';
import { Title } from './components/d-title';
import { DMath } from './components/d-math';
import { References } from './components/d-references';
@@ -53,7 +54,7 @@ const distillMain = function() {
/* Article will register controller which takes control from there */
const components = [
Abstract, Appendix, Article, Bibliography, Byline, Cite, CitationList, Code,
Footnote, FootnoteList, FrontMatter, Title, DMath, References, TOC, Figure,
Footnote, FootnoteList, FrontMatter, HoverBox, Title, DMath, References, TOC, Figure,
Slider, Interstitial
];
+7 -29
View File
@@ -1,6 +1,5 @@
import { Template } from '../mixins/template';
import { hover_cite, bibliography_cite } from '../helpers/citation';
import { HoverBox } from '../helpers/hover-box';
const T = Template('d-cite', `
<style>
@@ -35,31 +34,13 @@ figcaption .citation-number {
line-height: 1em;
}
.container {
position: absolute;
width: 100%;
left: 0;
z-index: 10000;
margin-top: 2em;
}
.dt-hover-box {
margin: 0 auto;
width: 400px;
max-width: 700px;
background-color: #FFF;
opacity: 0.95;
border: 1px solid rgba(0, 0, 0, 0.25);
padding: 8px 16px;
border-radius: 3px;
box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.2);
d-hover-box {
margin-top: 1.9em;
}
</style>
<div class="container">
<div id="hover-box" class="dt-hover-box"></div>
</div>
<d-hover-box id="hover-box"></d-hover-box>
<div id="citation-" class="citation"><slot></slot><span class="citation-number"></span></div>
`);
@@ -75,15 +56,12 @@ export class Cite extends T(HTMLElement) {
// }
connectedCallback() {
// this.notify();
this.hoverDiv = this.root.querySelector('.dt-hover-box');
this.outerSpan = this.root.querySelector('#citation-');
this.innerSpan = this.root.querySelector('.citation-number');
// this.outerSpan.id = `citation-${this.citeId}`;
// this.hoverDiv.id = `dt-cite-hover-box-${this.citeId}`;
// console.log(this, this.hoverDiv, this.outerSpan, this.innerSpan);
this.hoverbox = new HoverBox(this.hoverDiv, this.outerSpan);
this.hoverBox = this.root.querySelector('d-hover-box');
window.customElements.whenDefined('d-hover-box').then(() => {
this.hoverBox.listen(this);
});
}
disconnectedCallback() {
+13 -15
View File
@@ -1,5 +1,4 @@
import { Template } from '../mixins/template.js';
import { HoverBox } from '../helpers/hover-box';
const T = Template('d-footnote', `
<style>
@@ -9,7 +8,6 @@ d-math[block] {
}
:host {
position: relative;
}
sup {
@@ -34,23 +32,22 @@ span {
.dt-hover-box {
margin: 0 auto;
width: 400px;
max-width: 700px;
width: 704px;
max-width: 100vw;
background-color: #FFF;
opacity: 0.95;
border: 1px solid rgba(0, 0, 0, 0.25);
padding: 8px 16px;
border-radius: 3px;
box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.2);
box-sizing: border-box;
}
</style>
<div class="container">
<div id="hover-box" class="dt-hover-box">
<slot id="slot"></slot>
</div>
</div>
<d-hover-box>
<slot id="slot"></slot>
</d-hover-box>
<sup>
<span id="fn-" data-hover-ref=""></span>
@@ -79,23 +76,24 @@ export class Footnote extends T(HTMLElement) {
// const slot = this.shadowRoot.querySelector('#slot');
// console.warn(slot.textContent);
// slot.addEventListener('slotchange', this.notify);
this.hoverBox = this.root.querySelector('d-hover-box');
window.customElements.whenDefined('d-hover-box').then(() => {
this.hoverBox.listen(this);
});
// create numeric ID
Footnote.currentFootnoteId += 1;
const IdString = Footnote.currentFootnoteId.toString();
this.root.host.id = 'd-footnote-' + IdString;
// set up hidden hover box
const div = this.root.querySelector('.dt-hover-box');
div.id = 'dt-fn-hover-box-' + IdString;
const id = 'dt-fn-hover-box-' + IdString;
this.hoverBox.id = id
// set up visible footnote marker
const span = this.root.querySelector('#fn-');
span.setAttribute('id', 'fn-' + IdString);
span.setAttribute('data-hover-ref', div.id);
span.setAttribute('data-hover-ref', id);
span.textContent = IdString;
this.hoverbox = new HoverBox(div, span);
}
}
+132
View File
@@ -0,0 +1,132 @@
import { Template } from '../mixins/template.js';
const T = Template('d-hover-box', `
<style>
:host {
position: absolute;
width: 100%;
left: 0;
z-index: 10000;
display: none;
}
.container {
position: relative;
width: 704px;
max-width: 100vw;
margin: 0 auto;
}
.panel {
position: absolute;
top: 0;
left: 0;
width: 100%;
border: 1px solid rgba(0, 0, 0, 0.1);
background-color: rgb(250, 250, 250);
box-shadow: 0 0 7px rgba(0, 0, 0, 0.1);
border-radius: 4px;
padding: 10px;
box-sizing: border-box;
}
</style>
<div class="container">
<div class="panel">
<slot></slot>
</div>
</div>
`);
export class HoverBox extends T(HTMLElement) {
constructor() {
super();
}
connectedCallback() {
}
listen(element) {
console.log(element)
this.bindDivEvents(this);
this.bindTriggerEvents(element);
// this.style.display = "block";
}
bindDivEvents(element) {
// For mice, same behavior as hovering on links
element.addEventListener('mouseover', () => {
if (!this.visible) this.showAtNode(element);
this.stopTimeout();
});
element.addEventListener('mouseout', () => {
this.extendTimeout(500);
});
// Don't trigger body touchstart event when touching within box
element.addEventListener('touchstart', (event) => {
event.stopPropagation();
}, {passive: true});
// Close box when touching outside box
document.body.addEventListener('touchstart', () => {
this.hide();
}, {passive: true});
}
bindTriggerEvents(node) {
node.addEventListener('mouseover', () => {
if (!this.visible) {
this.showAtNode(node);
}
this.stopTimeout();
});
node.addEventListener('mouseout', () => {
this.extendTimeout(300);
});
node.addEventListener('touchstart', (event) => {
if (this.visible) {
this.hide();
} else {
this.showAtNode(node);
}
// Don't trigger body touchstart event when touching link
event.stopPropagation();
}, {passive: true});
}
show(position) {
this.visible = true;
this.style.display = 'block';
}
showAtNode(node) {
const bbox = node.getBoundingClientRect();
this.show([bbox.right, bbox.bottom]);
}
hide() {
this.visible = false;
this.style.display = 'none';
this.stopTimeout();
}
stopTimeout() {
if (this.timeout) {
clearTimeout(this.timeout);
}
}
extendTimeout(time) {
this.stopTimeout();
this.timeout = setTimeout(() => {
this.hide();
}, time);
}
}
-109
View File
@@ -1,109 +0,0 @@
// function make_hover_css(target_node, pos) {
// const pretty = window.innerWidth > 600;
// const padding = pretty? 18 : 12;
// const outer_padding = pretty ? 18 : 0;
// // const bbox = document.querySelector('body').getBoundingClientRect();
// const bbox = target_node.offsetParent.getBoundingClientRect();
// let left = pos[0] - bbox.left, top = pos[1] - bbox.top;
// let width = Math.min(window.innerWidth-2*outer_padding, 648);
// left = Math.min(left, window.innerWidth-width-outer_padding);
// width = width - 2 * padding;
// return (`position: absolute;
// background-color: #FFF;
// opacity: 0.95;
// max-width: ${width}px;
// top: ${top}px;
// left: ${left}px;
// border: 1px solid rgba(0, 0, 0, 0.25);
// padding: ${padding}px;
// border-radius: ${pretty? 3 : 0}px;
// box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.2);
// z-index: ${1e6};`);
// }
export class HoverBox {
constructor(contentHTML, triggerElement) {
this.visible = false;
// div hold teh contents of the box that will become visible
this.div = contentHTML;
this.bindDivEvents(this.div);
// triggerElement holds the element that needs to be hovered etc to show contents
this.triggerElement = triggerElement;
this.bindTriggerEvents(this.triggerElement);
this.hide();
}
bindDivEvents(node) {
// For mice, same behavior as hovering on links
this.div.addEventListener('mouseover', () => {
if (!this.visible) this.showAtNode(node);
this.stopTimeout();
});
this.div.addEventListener('mouseout', () => {
this.extendTimeout(500);
});
// Don't trigger body touchstart event when touching within box
this.div.addEventListener('touchstart', (event) => {
event.stopPropagation();
}, {passive: true});
// Close box when touching outside box
document.body.addEventListener('touchstart', () => {
this.hide();
}, {passive: true});
}
bindTriggerEvents(node) {
node.addEventListener('mouseover', () => {
if (!this.visible) {
this.showAtNode(node);
}
this.stopTimeout();
});
node.addEventListener('mouseout', () => {
this.extendTimeout(500);
});
node.addEventListener('touchstart', (event) => {
if (this.visible) {
this.hide();
} else {
this.showAtNode(node);
}
// Don't trigger body touchstart event when touching link
event.stopPropagation();
}, {passive: true});
}
show(position) {
this.visible = true;
// const css = make_hover_css(this.triggerElement, position);
this.div.setAttribute('style', 'display: block;' );
}
showAtNode(node) {
const bbox = node.getBoundingClientRect();
this.show([bbox.right, bbox.bottom]);
}
hide() {
this.visible = false;
this.div.setAttribute('style', 'display: none;');
this.stopTimeout();
}
stopTimeout() {
if (this.timeout) {
clearTimeout(this.timeout);
}
}
extendTimeout(time) {
this.stopTimeout();
this.timeout = setTimeout(() => {
this.hide();
}, time);
}
}
+3 -1
View File
@@ -10,7 +10,9 @@ html {
}
@media(min-width: 768px) {
font-size: 16px;
html {
font-size: 16px;
}
}
body {