From c9f05f5c6bb3b5da8196bf252e70bb57f153d0af Mon Sep 17 00:00:00 2001 From: zombieFox Date: Sun, 6 Jan 2019 07:06:33 +0000 Subject: [PATCH] [feature] adding tip --- css/base.css | 7 +-- css/button.css | 4 ++ css/form.css | 27 +++++++--- css/tip.css | 71 +++++++++++++++++++++++++ index.html | 6 ++- js/helper.js | 1 - js/init.js | 3 ++ js/tip.js | 138 +++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 245 insertions(+), 12 deletions(-) create mode 100644 css/tip.css create mode 100644 js/tip.js diff --git a/css/base.css b/css/base.css index 2b7eccef..f69ca95d 100644 --- a/css/base.css +++ b/css/base.css @@ -43,9 +43,10 @@ --breakpoint-xxl: 1600px; --z-index-link: 1000; --z-index-header: 2000; - --z-index-shade: 3000; - --z-index-modal: 4000; - --z-index-menu: 5000; + --z-index-tip: 3000; + --z-index-shade: 4000; + --z-index-modal: 5000; + --z-index-menu: 6000; } :root.is-link-block { diff --git a/css/button.css b/css/button.css index 1ef1ab3f..974e3223 100644 --- a/css/button.css +++ b/css/button.css @@ -69,6 +69,10 @@ button[disabled]:active, cursor: default; } +.button-text { + pointer-events: none; +} + button [class^="icon-"], button [class*=" icon-"], .button [class^="icon-"], diff --git a/css/form.css b/css/form.css index a444c5e5..9c934808 100644 --- a/css/form.css +++ b/css/form.css @@ -155,13 +155,13 @@ input[type="color"]::-webkit-color-swatch { border: 0; } -input[type="color"]+.label-button-color { +input[type="color"]+.input-label-button { padding-right: 2.25em; justify-content: center; align-items: center; } -input[type="color"]+.label-button-color:before { +input[type="color"]+.input-label-button:before { background-color: rgb(var(--accent)); content: ""; border-radius: 50%; @@ -208,6 +208,7 @@ input[type="radio"] { font-size: 1em; line-height: 1; cursor: pointer; + pointer-events: none; box-sizing: border-box; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } @@ -285,14 +286,28 @@ input[type="radio"]:checked:focus+label .label-icon { transform: scale(1.2); } -input[type="checkbox"]+.button-checkbox, -input[type="radio"]+.button-checkbox { +input[type="color"]+.input-label-button, +input[type="checkbox"]+.input-label-button, +input[type="radio"]+.input-label-button { justify-content: center; align-items: center; } -input[type="checkbox"]:checked+.button-checkbox, -input[type="radio"]:checked+.button-checkbox { +input[type="color"]:hover+.input-label-button, +input[type="color"]:focus+.input-label-button, +input[type="checkbox"]:hover+.input-label-button, +input[type="checkbox"]:focus+.input-label-button, +input[type="radio"]:hover+.input-label-button, +input[type="radio"]:focus+.input-label-button { + background-color: var(--gray-03); + border-bottom-color: rgb(var(--accent)); + color: var(--white); + outline: 0; +} + +input[type="color"]:checked+.input-label-button, +input[type="checkbox"]:checked+.input-label-button, +input[type="radio"]:checked+.input-label-button { border-bottom-color: rgb(var(--accent)); } diff --git a/css/tip.css b/css/tip.css new file mode 100644 index 00000000..65d0696e --- /dev/null +++ b/css/tip.css @@ -0,0 +1,71 @@ +.tip { + position: absolute; + max-width: 20em; + margin: 1em 1em; + left: 0; + top: 0; + opacity: 1; + z-index: var(--z-index-tip); + transition: opacity var(--animation-speed-fast) ease-in-out; + transform-origin: bottom center; + pointer-events: none; +} + +@keyframes grow { + 0% { + transform: translate(0, 0.2em) scale(0.95); + clip-path: circle(0 at 50% 100%); + } + + 100% { + transform: translate(0, 0) scale(1); + clip-path: circle(100% at 50% 100%); + } +} + +@keyframes shirnk { + 0% { + transform: translate(0, 0) scale(1); + clip-path: circle(100% at 50% 100%); + } + + 100% { + transform: translate(0, 0.2em) scale(0.95); + clip-path: circle(0 at 50% 100%); + } +} + +.tip-intro { + animation: grow var(--animation-speed-slow) 1; +} + +.tip-outro { + animation: shirnk var(--animation-speed-slow) 1; +} + +.tip-message { + padding: 0.5em 1em; + background-color: var(--gray-04); + border: 0; + border-radius: calc(var(--radius) * 2); + color: var(--gray-18); + font-size: 0.8em; + font-family: var(--font-regular); + text-align: center; + position: relative; + display: block; + z-index: 1; +} + +.tip-arrow { + border: 0.5em solid transparent; + border-top-color: var(--gray-04); + position: absolute; + width: 0; + height: 0; + top: 100%; + left: 50%; + display: block; + z-index: 2; + transform: translate(-50%, 0); +} diff --git a/index.html b/index.html index 0735f9c8..7f575d37 100644 --- a/index.html +++ b/index.html @@ -19,6 +19,7 @@ + @@ -52,7 +53,7 @@
-
@@ -64,7 +65,7 @@
-
@@ -291,6 +292,7 @@ + diff --git a/js/helper.js b/js/helper.js index 3d28e852..d879f7e5 100644 --- a/js/helper.js +++ b/js/helper.js @@ -233,7 +233,6 @@ var helper = (function() { function makeObject(string) { var _stringOrBooleanOrNumber = function(stringToTest) { - console.log(stringToTest); if (stringToTest == "true") { return true; } else if (stringToTest == "false") { diff --git a/js/init.js b/js/init.js index 8fe0a0c0..7990c530 100644 --- a/js/init.js +++ b/js/init.js @@ -38,5 +38,8 @@ clock.init(); // bind keyboard keys keyboard.init(); +// bind tips +tip.init(); + // render header height padding header.init(); diff --git a/js/tip.js b/js/tip.js new file mode 100644 index 00000000..985c6872 --- /dev/null +++ b/js/tip.js @@ -0,0 +1,138 @@ +var tip = (function() { + + var destroyTimer = null; + + var intervalId; + + var _bind = function() { + var allTip = helper.eA("[data-tip-options]"); + for (var i = 0; i < allTip.length; i++) { + var options = helper.makeObject(allTip[i].dataset.tipOptions); + _bind_tip(allTip[i]); + }; + }; + + var _bind_tip = function(tip) { + var options = helper.makeObject(tip.dataset.tipOptions); + var action = { + focus: function() { + tip.addEventListener("focus", function() { + if (options.delay) { + intervalId = setInterval(function() { + render(tip); + }, options.delay); + } else { + render(tip); + }; + }, false); + tip.addEventListener("blur", function() { + destroy(); + clearInterval(intervalId); + }, false); + }, + hover: function() { + tip.addEventListener("mouseover", function() { + if (options.delay) { + intervalId = setInterval(function() { + render(tip); + }, options.delay); + } else { + render(tip); + }; + }, false); + tip.addEventListener("mouseout", function() { + destroy(); + clearInterval(intervalId); + }, false); + } + }; + action[options.state](); + }; + + var delayDestroy = function() { + var allTipBox = helper.eA(".tip-box"); + for (var i = 0; i < allTipBox.length; i++) { + if (!allTipBox[i].classList.contains("is-opaque")) { + allTipBox[i].parentElement.removeChild(allTipBox[i]); + }; + }; + }; + + var destroy = function() { + var allTipBox = helper.eA(".tip-box"); + if (allTipBox[0]) { + for (var i = 0; i < allTipBox.length; i++) { + allTipBox[i].destroy(); + }; + }; + }; + + var render = function(tip) { + // console.log(tip.getBoundingClientRect()); + var options = helper.makeObject(tip.dataset.tipOptions); + var body = helper.e("body"); + var tipWrapper = document.createElement("div"); + tipWrapper.setAttribute("class", "tip tip-box is-transparent"); + var tipArrow = document.createElement("span"); + tipArrow.setAttribute("class", "tip-arrow"); + var tipMessage = document.createElement("p"); + tipMessage.setAttribute("class", "tip-message"); + tipMessage.textContent = options.message; + tipWrapper.destroy = function() { + if (tipWrapper.classList.contains("is-opaque")) { + helper.removeClass(tipWrapper, "is-opaque"); + helper.addClass(tipWrapper, "is-transparent"); + helper.removeClass(tipWrapper, "tip-intro"); + helper.addClass(tipWrapper, "tip-outro"); + } else { + tipWrapper.remove(); + }; + }; + tipWrapper.addEventListener("transitionend", function(event, elapsed) { + if (event.propertyName === "opacity" && getComputedStyle(this).opacity == 0) { + this.parentElement.removeChild(this); + }; + }.bind(tipWrapper), false); + + tipWrapper.appendChild(tipMessage); + tipWrapper.appendChild(tipArrow); + body.appendChild(tipWrapper); + tipWrapper.setAttribute("style", "width: " + (parseInt(tipWrapper.getBoundingClientRect().width, 10) + 2) + "px;"); + + var width = parseInt(tipWrapper.getBoundingClientRect().width); + var top = parseInt(tip.getBoundingClientRect().top, 10) + parseInt(pageYOffset, 10) - parseInt(tipWrapper.getBoundingClientRect().height, 10) - parseInt(getComputedStyle(tipWrapper).marginTop, 10) - parseInt(getComputedStyle(tipWrapper).marginBottom, 10); + var left = parseInt(tip.getBoundingClientRect().left, 10) + parseInt((tip.getBoundingClientRect().width / 2), 10) - parseInt(((width + parseInt(getComputedStyle(tipWrapper).marginLeft, 10) + parseInt(getComputedStyle(tipWrapper).marginRight, 10)) / 2), 10); + + tipWrapper.setAttribute("style", "width: " + width + "px; top: " + top + "px; left: " + left + "px"); + var style = { + top: tipWrapper.style.top, + width: tipWrapper.style.width + }; + + if (tipWrapper.getBoundingClientRect().left < parseInt(getComputedStyle(tipWrapper).marginLeft, 10)) { + // console.log("too far left"); + tipWrapper.setAttribute("style", "width: " + style.width + "; top: " + style.top + "; left: " + 0 + "px;"); + tipArrow.setAttribute("style", "left: " + (parseInt(tip.getBoundingClientRect().left, 10) + parseInt((tip.getBoundingClientRect().width / 2), 10) - parseInt(getComputedStyle(tipWrapper).marginLeft, 10)) + "px;"); + } else if (tipWrapper.getBoundingClientRect().right > (document.documentElement.clientWidth - parseInt(getComputedStyle(tipWrapper).marginLeft, 10))) { + // console.log("too far right"); + tipWrapper.setAttribute("style", "width: " + style.width + "; top: " + style.top + "; left: initial; right: " + 0 + "px;"); + tipArrow.setAttribute("style", "left: " + (-parseInt(tipWrapper.getBoundingClientRect().left, 10) + parseInt(tip.getBoundingClientRect().left, 10) + (parseInt((tip.getBoundingClientRect().width), 10) / 2)) + "px;"); + }; + + getComputedStyle(tipWrapper).opacity; + helper.removeClass(tipWrapper, "is-transparent"); + helper.addClass(tipWrapper, "is-opaque"); + helper.addClass(tipWrapper, "tip-intro"); + }; + + var init = function() { + _bind(); + }; + + // exposed methods + return { + destroy: destroy, + init: init + }; + +})();