From b74730a7eecbbca826aabd8575ab181bb589758f Mon Sep 17 00:00:00 2001 From: Laurent Blanes Date: Sat, 15 Apr 2017 04:04:49 +0900 Subject: [PATCH] upload the rest of the files --- css/index.css.map | 12 +++ example/index.html | 178 ++++++++++++++++++++++++++++++++++++++ src/directives/tooltip.js | 125 ++++++++++++++++++++++++++ 3 files changed, 315 insertions(+) create mode 100644 css/index.css.map create mode 100644 example/index.html create mode 100644 src/directives/tooltip.js diff --git a/css/index.css.map b/css/index.css.map new file mode 100644 index 0000000..5cd0b37 --- /dev/null +++ b/css/index.css.map @@ -0,0 +1,12 @@ +{ + "version": 3, + "file": "index.css", + "sources": [ + "../src/css/index.scss" + ], + "sourcesContent": [ + "$popper-background-color: #787878 !default;\n\n.vue-tooltip {\n background: $popper-background-color;\n box-sizing: border-box;\n color: #fff;\n min-width: 120px;\n max-width: 320px;\n padding: 6px 10px;\n border-radius: 3px;\n z-index: 100;\n box-shadow: 2px 2px 3px rgba(#000, 0.4);\n\n .vue-tooltip-content {\n text-align: center;\n }\n \n // .popper-close {\n // position: absolute;\n // top: 2px;\n // right: 4px;\n // color: black;\n // background: transparent;\n // border: none;\n \n // &:active,\n // &:focus {\n // outline: none;\n // }\n // }\n \n [x-arrow] {\n content: '';\n width: 0;\n height: 0;\n border-style: solid;\n position: absolute;\n margin: 5px;\n }\n \n &[x-placement^=\"top\"] {\n margin-bottom: 5px;\n \n [x-arrow] {\n border-width: 5px 5px 0 5px;\n border-color: $popper-background-color transparent transparent transparent;\n bottom: -5px;\n margin-top: 0;\n margin-bottom: 0;\n }\n }\n \n &[x-placement^=\"bottom\"] {\n margin-top: 5px;\n \n [x-arrow] {\n border-width: 0 5px 5px 5px;\n border-color: transparent transparent $popper-background-color transparent;\n top: -5px;\n margin-top: 0;\n margin-bottom: 0;\n }\n }\n \n &[x-placement^=\"right\"] {\n margin-left: 5px;\n \n [x-arrow] {\n border-width: 5px 5px 5px 0;\n border-color: transparent $popper-background-color transparent transparent;\n left: -5px;\n margin-left: 0;\n margin-right: 0;\n }\n }\n \n &[x-placement^=\"left\"] {\n margin-right: 5px;\n \n [x-arrow] {\n border-width: 5px 0 5px 5px;\n border-color: transparent transparent transparent $popper-background-color;\n right: -5px;\n margin-left: 0;\n margin-right: 0;\n }\n }\n}" + ], + "names": [], + "mappings": "AAEA,AAAA,YAAY,CAAC;EACT,UAAU,EAHY,OAAO;EAI7B,UAAU,EAAE,UAAU;EACtB,KAAK,EAAE,IAAI;EACX,SAAS,EAAE,KAAK;EAChB,SAAS,EAAE,KAAK;EAChB,OAAO,EAAE,QAAQ;EACjB,aAAa,EAAE,GAAG;EAClB,OAAO,EAAE,GAAG;EACZ,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAM,kBAAI,GA4EpC;EArFD,AAWI,YAXQ,CAWR,oBAAoB,CAAC;IACjB,UAAU,EAAE,MAAM,GACrB;EAbL,AA6BI,YA7BQ,EA6BR,AAAA,OAAC,AAAA,EAAS;IACN,OAAO,EAAE,EAAE;IACX,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;IACT,YAAY,EAAE,KAAK;IACnB,QAAQ,EAAE,QAAQ;IAClB,MAAM,EAAE,GAAG,GACd;EApCL,AAsCI,YAtCQ,CAsCR,AAAA,WAAE,EAAa,KAAK,AAAlB,EAAoB;IAClB,aAAa,EAAE,GAAG,GASrB;IAhDL,AAyCQ,YAzCI,CAsCR,AAAA,WAAE,EAAa,KAAK,AAAlB,GAGE,AAAA,OAAC,AAAA,EAAS;MACN,YAAY,EAAE,aAAa;MAC3B,YAAY,EA7CE,OAAO,CA6CkB,WAAW,CAAC,WAAW,CAAC,WAAW;MAC1E,MAAM,EAAE,IAAI;MACZ,UAAU,EAAE,CAAC;MACb,aAAa,EAAE,CAAC,GACnB;EA/CT,AAkDI,YAlDQ,CAkDR,AAAA,WAAE,EAAa,QAAQ,AAArB,EAAuB;IACrB,UAAU,EAAE,GAAG,GASlB;IA5DL,AAqDQ,YArDI,CAkDR,AAAA,WAAE,EAAa,QAAQ,AAArB,GAGE,AAAA,OAAC,AAAA,EAAS;MACN,YAAY,EAAE,aAAa;MAC3B,YAAY,EAAE,WAAW,CAAC,WAAW,CAzDvB,OAAO,CAyD0C,WAAW;MAC1E,GAAG,EAAE,IAAI;MACT,UAAU,EAAE,CAAC;MACb,aAAa,EAAE,CAAC,GACnB;EA3DT,AA8DI,YA9DQ,CA8DR,AAAA,WAAE,EAAa,OAAO,AAApB,EAAsB;IACpB,WAAW,EAAE,GAAG,GASnB;IAxEL,AAiEQ,YAjEI,CA8DR,AAAA,WAAE,EAAa,OAAO,AAApB,GAGE,AAAA,OAAC,AAAA,EAAS;MACN,YAAY,EAAE,aAAa;MAC3B,YAAY,EAAE,WAAW,CArEX,OAAO,CAqE8B,WAAW,CAAC,WAAW;MAC1E,IAAI,EAAE,IAAI;MACV,WAAW,EAAE,CAAC;MACd,YAAY,EAAE,CAAC,GAClB;EAvET,AA0EI,YA1EQ,CA0ER,AAAA,WAAE,EAAa,MAAM,AAAnB,EAAqB;IACnB,YAAY,EAAE,GAAG,GASpB;IApFL,AA6EQ,YA7EI,CA0ER,AAAA,WAAE,EAAa,MAAM,AAAnB,GAGE,AAAA,OAAC,AAAA,EAAS;MACN,YAAY,EAAE,aAAa;MAC3B,YAAY,EAAE,WAAW,CAAC,WAAW,CAAC,WAAW,CAjFnC,OAAO;MAkFrB,KAAK,EAAE,IAAI;MACX,WAAW,EAAE,CAAC;MACd,YAAY,EAAE,CAAC,GAClB" +} \ No newline at end of file diff --git a/example/index.html b/example/index.html new file mode 100644 index 0000000..a112589 --- /dev/null +++ b/example/index.html @@ -0,0 +1,178 @@ + + + Tooltip Example + + + + + + + +
+

Vue.js Tooltip directive Vue.js v2+

+
+

Usage

+ +

With Webpack, Rollup, etc...

+

+


+// in your js file
+import Vue from 'vue';
+import Tooltip from 'vue-directive-tooltip';
+// or require('vue-directive-tooltip');
+import App from './App.vue';
+                    
+

+ +

With tag directly in the page

+

+


+<link rel="stylesheet" href="path/to/css/index.css">
+<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
+<script src="path/to/vueDirectiveTooltip.js"></script>
+                    
+

+
+
+

Positioning

+

+ Default position + <span v-tooltip="'I am on the bottom'"... +

+

+ Position right + <span v-tooltip.right="'I am on the right'"... +

+

+ Position top + <span v-tooltip.top="'I am on the top'"... +

+

+ I need a longer sentence to position left + <span v-tooltip.left="'I am on the left'"... +

+
+
+

Options

+ +

Content

+

+ Simple way to set text + <span v-tooltip="'simple way'"... +

+

+ "Option" way to set text + <span v-tooltip="{ content: 'option way' }"... +

+ +

Visibility

+

+ In case you need to hide a tooltip, you can use the visible option +

+

+ <span v-tooltip="{ content: 'change the visibility', visible: }"... +

+

+ +

+ +

Custom CSS classes

+

+ Add your custom CSS classes to change the tooltip appearance +

+

+ <span v-tooltip="{ content: 'custom class', class: 'tooltip-custom tooltip-other-custom' }"... +

+

+ CSS +


+.vue-tooltip.tooltip-custom {
+    background-color: red;
+}
+
+.vue-tooltip.tooltip-custom[x-placement^="top"] [x-arrow] {
+    border-top-color: red;
+}
+
+.vue-tooltip.tooltip-custom[x-placement^="bottom"] [x-arrow] {
+    border-bottom-color: red;
+}
+
+.vue-tooltip.tooltip-custom[x-placement^="left"] [x-arrow] {
+    border-left-color: red;
+}
+
+.vue-tooltip.tooltip-custom[x-placement^="right"] [x-arrow] {
+    border-right-color: red;
+}
+                    
+

+
+
+ + + + \ No newline at end of file diff --git a/src/directives/tooltip.js b/src/directives/tooltip.js new file mode 100644 index 0000000..e04c21f --- /dev/null +++ b/src/directives/tooltip.js @@ -0,0 +1,125 @@ +/** + * @author: laurent blanes + */ +import Popper from 'popper.js'; + +const BASE_CLASS = 'vue-tooltip'; + +/** + * usage: + * + * // basic usage: + *
+ * or + *
+ * + * // change position of tooltip + * // options: bottom (default) | top | left | right + *
+ * + * // add custom class + *
+ * + * // toggle visibility + *
+ */ +export default { + name: 'tooltip', + config: {}, + install (Vue) { + Vue.directive('tooltip', { + bind (el, binding, vnode) { + let $popper = null; + let placement = 'bottom'; + + if (binding.modifiers.left) { + placement = 'left'; + } else if (binding.modifiers.right) { + placement = 'right'; + } else if (binding.modifiers.top) { + placement = 'top'; + } else if (binding.modifiers.bottom) { + placement = 'bottom'; + } + + // wrapper + $popper = document.createElement('div'); + $popper.setAttribute('class', BASE_CLASS); + Popper.Utils.setStyles($popper, {visibility: 'hidden'}); + + // make arrow + let $arrow = document.createElement('div'); + $arrow.setAttribute('x-arrow', ''); + $popper.appendChild($arrow); + + // make content container + let $content = document.createElement('div'); + $content.setAttribute('class', 'vue-tooltip-content'); + $popper.appendChild($content); + + document.querySelector('body').appendChild($popper); + + const options = Object.assign({}, + binding.value, + { + placement, + onCreate (e) { + setProperties(el, binding); + setAttributes($popper, $content, el); + }, + onUpdate (e) { + setAttributes($popper, $content, el); + } + } + ); + el.popper = new Popper(el, $popper, options); + }, + inserted (el, binding, vnode, oldVnode) { + el.addEventListener('mouseover', onMouseOver); + el.addEventListener('mouseout', onMouseOut); + el.addEventListener('mouseleave', onMouseOut); + }, + componentUpdated (el, binding, vnode, oldVnode) { + setProperties(el, binding); + }, + unbind (el, binding, vnode, oldVnode) { + el.removeEventListener('mouseover', onMouseOver); + el.removeEventListener('mouseout', onMouseOut); + el.removeEventListener('mouseleave', onMouseOut); + document.querySelector('body').removeChild(el.popper.popper); + } + }); + } +}; + +function setProperties (el, binding) { + if (typeof binding.value === 'string') { + el.popper._class = ''; + el.popper._content = binding.value; + el.popper._visible = true; + } else { + el.popper._class = binding.value.class || ''; + el.popper._content = binding.value.content; + el.popper._visible = binding.value.visible !== false; + } +} + +function setAttributes ($popper, $content, el) { + $content.innerHTML = el.popper._content; + Popper.Utils.setStyles(el.popper.popper, { + display: el.popper._visible ? 'inline-block' : 'none' + }); + const classes = `${BASE_CLASS} ${el.popper._class}`; + $popper.setAttribute('class', classes.trim()); +} + +function onMouseOver (e) { + const el = e.target; + Popper.Utils.setStyles(el.popper.popper, {visibility: 'visible'}); + el.popper.update(); +} + +function onMouseOut (e) { + const el = e.target; + Popper.Utils.setStyles(el.popper.popper, {visibility: 'hidden'}); +}