Fixed #122 - Implemented Tooltip

pull/132/head
cagataycivici 2019-12-26 21:30:07 +03:00
parent 5e2e72b7df
commit d3a3e0fe0e
11 changed files with 481 additions and 3 deletions

2
exports/tooltip.js Normal file
View File

@ -0,0 +1,2 @@
'use strict';
module.exports = require('./components/tooltip/Tooltip.js');

View File

@ -1,6 +1,6 @@
{
"name": "primevue",
"version": "1.0.0-rc.3",
"version": "1.0.0-rc.4-SNAPSHOT",
"repository": {
"type": "git",
"url": "https://github.com/primefaces/primevue.git"

View File

@ -1,6 +1,6 @@
<template>
<div class="content-section layout-footer clearfix">
<span>PrimeVUE 1.0.0-rc.3</span>
<span>PrimeVue 1.0.0-rc.4</span>
<div class="footer-links">
<a href="https://github.com/primefaces/primevue"><i class=" icon-github fa fa-github-square"></i></a>
<a href="https://twitter.com/primevue"><i class="icon-twitter fa fa-twitter-square"></i></a>

View File

@ -78,6 +78,7 @@
<router-link to="/dialog">Dialog</router-link>
<router-link to="/overlaypanel">OverlayPanel</router-link>
<router-link to="/sidebar">Sidebar</router-link>
<router-link to="/tooltip">Tooltip</router-link>
</div>
<span>

View File

@ -4,4 +4,5 @@
@import '../../components/inputtext/InputText.css';
@import '../../components/password/Password.css';
@import '../../components/radiobutton/RadioButton.css';
@import '../../components/splitbutton/SplitButton.css';
@import '../../components/splitbutton/SplitButton.css';
@import '../../components/tooltip/Tooltip.css';

View File

@ -0,0 +1,67 @@
.p-tooltip {
position:absolute;
display:none;
padding: .25em .5em;
max-width: 12.5em;
}
.p-tooltip.p-tooltip-right,
.p-tooltip.p-tooltip-left {
padding: 0 .25em;
}
.p-tooltip.p-tooltip-top,
.p-tooltip.p-tooltip-bottom {
padding:.25em 0;
}
.p-tooltip .p-tooltip-text {
padding: .125em .5em;
background-color: rgb(76, 76, 76);
color: #ffffff;
white-space: pre-line;
}
.p-tooltip-arrow {
position: absolute;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
}
.p-tooltip-right .p-tooltip-arrow {
top: 50%;
left: 0;
margin-top: -.25em;
border-width: .25em .25em .25em 0;
border-right-color: rgb(76, 76, 76);
}
.p-tooltip-left .p-tooltip-arrow {
top: 50%;
right: 0;
margin-top: -.25em;
border-width: .25em 0 .25em .25em;
border-left-color: rgb(76, 76, 76);
}
.p-tooltip.p-tooltip-top {
padding: .25em 0;
}
.p-tooltip-top .p-tooltip-arrow {
bottom: 0;
left: 50%;
margin-left: -.25em;
border-width: .25em .25em 0;
border-top-color: rgb(76, 76, 76);
}
.p-tooltip-bottom .p-tooltip-arrow {
top: 0;
left: 50%;
margin-left: -.25em;
border-width: 0 .25em .25em;
border-bottom-color: rgb(76, 76, 76);
}

View File

@ -0,0 +1,226 @@
import UniqueComponentId from '../utils/UniqueComponentId';
import DomHandler from '../utils/DomHandler';
function bindEvents(el) {
const modifiers = el.$_ptooltipModifiers;
if (modifiers.focus) {
el.addEventListener('focus', onFocus);
el.addEventListener('blur', onBlur);
}
else {
el.addEventListener('mouseenter', onMouseEnter);
el.addEventListener('mouseleave', onMouseLeave);
el.addEventListener('click', onClick);
}
}
function unbindEvents(el) {
const modifiers = el.$_ptooltipModifiers;
if (modifiers.focus) {
el.removeEventListener('focus', onFocus);
el.removeEventListener('blur', onBlur);
}
else {
el.removeEventListener('mouseenter', onMouseEnter);
el.removeEventListener('mouseleave', onMouseLeave);
el.removeEventListener('click', onClick);
}
//this.unbindDocumentResizeListener();
}
function onMouseEnter(event) {
show(event.currentTarget);
}
function onMouseLeave(event) {
hide(event.currentTarget);
}
function onFocus(event) {
show(event.currentTarget);
}
function onBlur(event) {
hide(event.currentTarget);
}
function onClick(event) {
hide(event.currentTarget);
}
function show(el) {
if (!el.$_ptooltipValue) {
return;
}
let tooltipElement = create(el);
align(el);
DomHandler.fadeIn(tooltipElement, 250);
tooltipElement.style.zIndex = ++DomHandler.zindex;
}
function hide(el) {
remove(el);
}
function getTooltipElement(el) {
return document.getElementById(el.$_ptooltipId);
}
function create(el) {
const id = UniqueComponentId() + '_tooltip';
el.$_ptooltipId = id;
let container = document.createElement('div');
container.id = id;
let tooltipArrow = document.createElement('div');
tooltipArrow.className = 'p-tooltip-arrow';
container.appendChild(tooltipArrow);
let tooltipText = document.createElement('div');
tooltipText.className = 'p-tooltip-text';
tooltipText.innerHTML = el.$_ptooltipValue;
container.appendChild(tooltipText);
document.body.appendChild(container);
container.style.display = 'inline-block';
return container;
}
function remove(el) {
let tooltipElement = getTooltipElement(el);
if (tooltipElement && tooltipElement.parentElement) {
document.body.removeChild(tooltipElement);
}
el.$_ptooltipId = null;
}
function align(el) {
const modifiers = el.$_ptooltipModifiers;
if (modifiers.top) {
alignTop(el);
if (isOutOfBounds(el)) {
alignBottom(el);
}
}
else if (modifiers.left) {
alignLeft(el);
if (isOutOfBounds(el)) {
alignRight(el);
if (isOutOfBounds(el)) {
alignTop(el);
if (isOutOfBounds(el)) {
alignBottom(el);
}
}
}
}
else if (modifiers.bottom) {
alignBottom(el);
if (isOutOfBounds(el)) {
alignTop(el);
}
}
else {
alignRight(el);
if (isOutOfBounds(el)) {
alignLeft(el);
if (isOutOfBounds(el)) {
alignTop(el);
if (isOutOfBounds(el)) {
alignBottom(el);
}
}
}
}
}
function getHostOffset(el) {
let offset = el.getBoundingClientRect();
let targetLeft = offset.left + DomHandler.getWindowScrollLeft();
let targetTop = offset.top + DomHandler.getWindowScrollTop();
return {left: targetLeft, top: targetTop};
}
function alignRight(el) {
preAlign(el, 'right');
let tooltipElement = getTooltipElement(el);
let hostOffset = getHostOffset(el);
let left = hostOffset.left + DomHandler.getOuterWidth(el);
let top = hostOffset.top + (DomHandler.getOuterHeight(el) - DomHandler.getOuterHeight(tooltipElement)) / 2;
tooltipElement.style.left = left + 'px';
tooltipElement.style.top = top + 'px';
}
function alignLeft(el) {
preAlign(el, 'left');
let tooltipElement = getTooltipElement(el);
let hostOffset = getHostOffset(el);
let left = hostOffset.left - DomHandler.getOuterWidth(tooltipElement);
let top = hostOffset.top + (DomHandler.getOuterHeight(el) - DomHandler.getOuterHeight(tooltipElement)) / 2;
tooltipElement.style.left = left + 'px';
tooltipElement.style.top = top + 'px';
}
function alignTop(el) {
preAlign(el, 'top');
let tooltipElement = getTooltipElement(el);
let hostOffset = getHostOffset(el);
let left = hostOffset.left + (DomHandler.getOuterWidth(el) - DomHandler.getOuterWidth(tooltipElement)) / 2;
let top = hostOffset.top - DomHandler.getOuterHeight(tooltipElement);
tooltipElement.style.left = left + 'px';
tooltipElement.style.top = top + 'px';
}
function alignBottom(el) {
preAlign(el, 'bottom');
let tooltipElement = getTooltipElement(el);
let hostOffset = getHostOffset(el);
let left = hostOffset.left + (DomHandler.getOuterWidth(el) - DomHandler.getOuterWidth(tooltipElement)) / 2;
let top = hostOffset.top + DomHandler.getOuterHeight(el);
tooltipElement.style.left = left + 'px';
tooltipElement.style.top = top + 'px';
}
function preAlign(el, position) {
let tooltipElement = getTooltipElement(el);
tooltipElement.style.left = -999 + 'px';
tooltipElement.style.top = -999 + 'px';
tooltipElement.className = 'p-tooltip p-component p-tooltip-' + position;
}
function isOutOfBounds(el) {
let tooltipElement = getTooltipElement(el);
let offset = tooltipElement.getBoundingClientRect();
let targetTop = offset.top;
let targetLeft = offset.left;
let width = DomHandler.getOuterWidth(tooltipElement);
let height = DomHandler.getOuterHeight(tooltipElement);
let viewport = DomHandler.getViewport();
return (targetLeft + width > viewport.width) || (targetLeft < 0) || (targetTop < 0) || (targetTop + height > viewport.height);
}
const Tooltip = {
bind(el, options) {
el.$_ptooltipModifiers = options.modifiers;
el.$_ptooltipValue = options.value;
bindEvents(el);
},
unbind(el) {
remove(el);
unbindEvents(el);
}
};
export default Tooltip;

View File

@ -63,6 +63,7 @@ import TreeTable from './components/treetable/TreeTable';
import Toast from './components/toast/Toast';
import ToastService from './components/toast/ToastService';
import Toolbar from './components/toolbar/Toolbar';
import Tooltip from './components/tooltip/Tooltip';
import ToggleButton from './components/togglebutton/ToggleButton';
import TriStateCheckbox from './components/tristatecheckbox/TriStateCheckbox';
import InputMask from './components/inputmask/InputMask';
@ -80,6 +81,8 @@ import '@fullcalendar/timegrid/main.min.css';
Vue.use(ToastService);
Vue.directive('tooltip', Tooltip);
Vue.config.productionTip = false;
Vue.component('Accordion', Accordion);

View File

@ -492,6 +492,11 @@ export default new Router({
name: 'toolbar',
component: () => import('./views/toolbar/ToolbarDemo.vue')
},
{
path: '/tooltip',
name: 'tooltip',
component: () => import('./views/tooltip/TooltipDemo.vue')
},
{
path: '/tree',
name: 'tree',

View File

@ -0,0 +1,50 @@
<template>
<div>
<div class="content-section introduction">
<div class="feature-intro">
<h1>Tooltip</h1>
<p>Tooltip directive provides advisory information for a component.</p>
</div>
</div>
<div class="content-section implementation">
<h3>Positions</h3>
<div class="p-grid p-fluid">
<div class="p-col-12 p-md-3">
<InputText type="text" placeholder="Right" v-tooltip.right="'Enter your username'" />
</div>
<div class="p-col-12 p-md-3">
<InputText type="text" placeholder="Top" v-tooltip.top="'Enter your username'" />
</div>
<div class="p-col-12 p-md-3">
<InputText type="text" placeholder="Bottom" v-tooltip.bottom="'Enter your username'" />
</div>
<div class="p-col-12 p-md-3">
<InputText type="text" placeholder="Left" v-tooltip.left="'Enter your username'" />
</div>
</div>
<h3>Focus and Blur</h3>
<InputText type="text" placeholder="Focus" v-tooltip.bottom.focus="'Enter your username'" />
<h3>Button</h3>
<Button type="button" label="Save" icon="pi pi-check" v-tooltip="'Click to proceed'" />
</div>
<TooltipDoc />
</div>
</template>
<script>
import TooltipDoc from './TooltipDoc';
export default {
components: {
'TooltipDoc': TooltipDoc
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,123 @@
<template>
<div class="content-section documentation">
<TabView>
<TabPanel header="Documentation">
<h3>Getting Started</h3>
<p>Tooltip is a directive that needs to be imported and configured with a name of your choice.</p>
<CodeHighlight>
import Tooltip from 'primevue/tooltip';
Vue.directive('tooltip', Tooltip);
</CodeHighlight>
<p>Tooltip can also be configured locally using the directives property of your component.</p>
<CodeHighlight>
directives: {
tooltip: Tooltip
}
</CodeHighlight>
<p>Once the tooltip is configured, it can be attached to a target using the v- prefix.</p>
<CodeHighlight>
<template v-pre>
&lt;InputText type="text" v-tooltip="'Enter your username'" /&gt;
</template>
</CodeHighlight>
<h3>Positions</h3>
<p>There are four choices to position the tooltip, default value is "right" and alternatives are "top", "bottom", "left". Position is specified using a modifier.</p>
<CodeHighlight>
<template v-pre>
&lt;InputText type="text" v-tooltip.right="'Enter your username'" /&gt;
&lt;InputText type="text" v-tooltip.top="'Enter your username'" /&gt;
&lt;InputText type="text" v-tooltip.bottom="'Enter your username'" /&gt;
&lt;InputText type="text" v-tooltip.top="'Enter your username'" /&gt;
</template>
</CodeHighlight>
<h3>Events</h3>
<p>Tooltip gets displayed on hover event of its target by default, other option is the focus event to display and blur to hide.</p>
<CodeHighlight>
<template v-pre>
&lt;InputText type="text" v-tooltip.focus="'Enter your username'" /&gt;
</template>
</CodeHighlight>
<h3>Modifiers</h3>
<p>As seen in positions and event sections, tooltip is configured via modifiers that can be chained. Tooltip below,
gets displayed at the top of the input at focus event.
</p>
<CodeHighlight>
<template v-pre>
&lt;InputText type="text" v-tooltip.top.focus="'Enter your username'" /&gt;
</template>
</CodeHighlight>
<h3>Styling</h3>
<p>Following is the list of structural style classes, for theming classes visit <router-link to="/theming">theming</router-link> page.</p>
<div class="doc-tablewrapper">
<table class="doc-table">
<thead>
<tr>
<th>Name</th>
<th>Element</th>
</tr>
</thead>
<tbody>
<tr>
<td>p-tooltip</td>
<td>Input element.</td>
</tr>
<tr>
<td>p-tooltip-arrow</td>
<td>Arrow of the tooltip.</td>
</tr>
<tr>
<td>p-tooltip-text</td>
<td>Text of the tooltip</td>
</tr>
</tbody>
</table>
</div>
<h3>Dependencies</h3>
<p>None.</p>
</TabPanel>
<TabPanel header="Source">
<a href="https://github.com/primefaces/primevue/tree/master/src/views/tooltip" class="btn-viewsource" target="_blank" rel="noopener noreferrer">
<span>View on GitHub</span>
</a>
<CodeHighlight>
<template v-pre>
&lt;h3&gt;Positions&lt;/h3&gt;
&lt;div class="p-grid p-fluid"&gt;
&lt;div class="p-col-12 p-md-3"&gt;
&lt;InputText type="text" placeholder="Right" v-tooltip.right="'Enter your username'" /&gt;
&lt;/div&gt;
&lt;div class="p-col-12 p-md-3"&gt;
&lt;InputText type="text" placeholder="Top" v-tooltip.top="'Enter your username'" /&gt;
&lt;/div&gt;
&lt;div class="p-col-12 p-md-3"&gt;
&lt;InputText type="text" placeholder="Bottom" v-tooltip.bottom="'Enter your username'" /&gt;
&lt;/div&gt;
&lt;div class="p-col-12 p-md-3"&gt;
&lt;InputText type="text" placeholder="Left" v-tooltip.left="'Enter your username'" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3&gt;Focus and Blur&lt;/h3&gt;
&lt;InputText type="text" placeholder="Focus" v-tooltip.bottom.focus="'Enter your username'" /&gt;
&lt;h3&gt;Button&lt;/h3&gt;
&lt;Button type="button" label="Save" icon="pi pi-check" v-tooltip="'Click to proceed'" /&gt;
</template>
</CodeHighlight>
<CodeHighlight lang="javascript">
export default {}
</CodeHighlight>
</TabPanel>
</TabView>
</div>
</template>