Initial version
This commit is contained in:
parent
db848cd568
commit
e3414c9d44
13
package-lock.json
generated
Normal file
13
package-lock.json
generated
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "tp-tooltip",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"requires": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@tp/helpers": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://verdaccio.codeblob.work/@tp%2fhelpers/-/helpers-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-0RcwkVBsZoa2jaOGwf0QNBHIC1vA/8G1rsvWC1j20tyyzZBOqGGOwvgnLN1TEP3C8zT4+oUMlQbu6DmkpW9T3A=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,18 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "tp-element",
|
"name": "tp-tooltip",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "tp-element.js",
|
"main": "tp-tooltip.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://gitea.codeblob.work/tp-elements/tp-element.git"
|
"url": "https://gitea.codeblob.work/tp-elements/tp-tooltip.git"
|
||||||
},
|
},
|
||||||
"author": "trading_peter",
|
"author": "trading_peter",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@tp/helpers": "^1.0.0",
|
||||||
"lit": "^2.2.0"
|
"lit": "^2.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
/**
|
|
||||||
@license
|
|
||||||
Copyright (c) 2022 trading_peter
|
|
||||||
This program is available under Apache License Version 2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { LitElement, html, css } from 'lit';
|
|
||||||
|
|
||||||
class TpElement extends LitElement {
|
|
||||||
static get styles() {
|
|
||||||
return [
|
|
||||||
css`
|
|
||||||
:host {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { } = this;
|
|
||||||
|
|
||||||
return html`
|
|
||||||
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get properties() {
|
|
||||||
return { };
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
window.customElements.define('tp-element', TpElement);
|
|
100
tp-tooltip-mixin.js
Normal file
100
tp-tooltip-mixin.js
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/**
|
||||||
|
@license
|
||||||
|
Copyright (c) 2022 trading_peter
|
||||||
|
This program is available under Apache License Version 2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import './tp-tooltip.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Elements implementing this mixin are able to show tooltip on mouse over.
|
||||||
|
*
|
||||||
|
* ## Example
|
||||||
|
* ```html
|
||||||
|
* <x-foo tooltip="Show this text in the tooltip"></x-foo>
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @polymer
|
||||||
|
* @mixinFunction
|
||||||
|
*/
|
||||||
|
export const Tooltip = function(superClass) {
|
||||||
|
return class extends superClass {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Text to show in the tooltip.
|
||||||
|
*/
|
||||||
|
tooltip: { type: String },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vertical align of the tooltip.
|
||||||
|
* Supported are `bottom` and `top`.
|
||||||
|
*/
|
||||||
|
tooltipValign: { type: String }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.tooltipValign = 'bottom';
|
||||||
|
this._showTooltip = this._showTooltip.bind(this);
|
||||||
|
this._hideTooltip = this._hideTooltip.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
set tooltip(val) {
|
||||||
|
const oldTooltip = this.tooltip;
|
||||||
|
this._tooltip = val;
|
||||||
|
this._tooltipChanged(this.tooltip, oldTooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
get tooltip() {
|
||||||
|
return this._tooltip;
|
||||||
|
}
|
||||||
|
|
||||||
|
_tooltipChanged(newTooltip, oldTooltip) {
|
||||||
|
if (oldTooltip) {
|
||||||
|
this.removeEventListener('mouseenter', this._showTooltip);
|
||||||
|
this.removeEventListener('focus', this._showTooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newTooltip && newTooltip !== '') {
|
||||||
|
this.addEventListener('mouseenter', this._showTooltip);
|
||||||
|
this.addEventListener('focus', this._showTooltip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_showTooltip() {
|
||||||
|
if (this._tooltipInstance || !this.tooltip || this.tooltip === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const tooltip = document.createElement('tp-tooltip');
|
||||||
|
tooltip.innerHTML = this.tooltip;
|
||||||
|
tooltip.valign = this.tooltipValign;
|
||||||
|
tooltip.target = this;
|
||||||
|
this._tooltipInstance = tooltip;
|
||||||
|
|
||||||
|
this.addEventListener('mouseleave', this._hideTooltip);
|
||||||
|
this.addEventListener('blur', this._hideTooltip);
|
||||||
|
this.addEventListener('click', this._hideTooltip);
|
||||||
|
|
||||||
|
document.body.appendChild(this._tooltipInstance);
|
||||||
|
this._tooltipInstance.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
_hideTooltip() {
|
||||||
|
if (!this._tooltipInstance) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._tooltipInstance.hide(function() {
|
||||||
|
if (this._tooltipInstance) {
|
||||||
|
document.body.removeChild(this._tooltipInstance);
|
||||||
|
this.removeEventListener('mouseleave', this._hideTooltip);
|
||||||
|
this.removeEventListener('blur', this._hideTooltip);
|
||||||
|
this.removeEventListener('click', this._hideTooltip);
|
||||||
|
this._tooltipInstance = null;
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
74
tp-tooltip-wrapper.js
Normal file
74
tp-tooltip-wrapper.js
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
@license
|
||||||
|
Copyright (c) 2022 trading_peter
|
||||||
|
This program is available under Apache License Version 2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { LitElement, html, css } from 'lit';
|
||||||
|
import { Tooltip } from './tp-tooltip-mixin.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
# tp-tooltip-wrapper
|
||||||
|
|
||||||
|
This element can be used to add a tooltip to elements that don't implement the tooltip mixin.
|
||||||
|
It is a simple wrapper. It can be shown conditionally based on the value of `disabled`.
|
||||||
|
For this you have to use the `text` property instead of the inherited `tooltip` property.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
```html
|
||||||
|
<tp-tooltip-wrapper tooltip="Text of the tooltip">
|
||||||
|
<div>Content with a tooltip</div>
|
||||||
|
</tp-tooltip-wrapper>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Styling
|
||||||
|
Name | Type | Default | Description
|
||||||
|
---|---|---
|
||||||
|
--tp-tooltip-wrapper | mixin || Styling on :host.
|
||||||
|
|
||||||
|
*/
|
||||||
|
class TpTooltipWrapper extends Tooltip(LitElement) {
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<slot></slot>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
text: { type: String },
|
||||||
|
disabled: { type: Boolean }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldUpdate(changes) {
|
||||||
|
if (changes.has('text') || changes.has('disabled')) {
|
||||||
|
this._setTooltipText(this.text, this.disabled);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this._hideTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
_setTooltipText(text, disabled) {
|
||||||
|
this.tooltip = disabled ? '' : text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.customElements.define('tp-tooltip-wrapper', TpTooltipWrapper);
|
124
tp-tooltip.js
Normal file
124
tp-tooltip.js
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2020 EDV Wasmeier
|
||||||
|
This program is available under Apache License Version 2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { LitElement, html, css } from 'lit';
|
||||||
|
import { Position } from '@tp/helpers/position.js';
|
||||||
|
|
||||||
|
/*
|
||||||
|
# tp-tooltip
|
||||||
|
|
||||||
|
This element is used by `tp-tooltip-mixin` to show a tooltip on the implementing element.
|
||||||
|
It is not meant to be used stand alone.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
```html
|
||||||
|
<x-foo tooltip="Show this text in the tooltip"></x-foo>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Styling
|
||||||
|
Name | Type | Default | Description
|
||||||
|
---|---|---
|
||||||
|
--tp-tooltip-spacing | var | 5px | Spacing between target and the tooltip.
|
||||||
|
|
||||||
|
*/
|
||||||
|
class TpTooltip extends Position(LitElement) {
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
:host {
|
||||||
|
display: none;
|
||||||
|
opacity: 0;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
background: #1B1B1B;
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 2px;
|
||||||
|
transition: transform 80ms, opacity 180ms;
|
||||||
|
transform: scale(0.90);
|
||||||
|
will-change: transform, opacity;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host([visible]) {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<div class="wrap"><slot></slot></div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
/**
|
||||||
|
* Element to align the tooltip to.
|
||||||
|
*/
|
||||||
|
target: { type: Object },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the tooltip is currently visible.
|
||||||
|
*/
|
||||||
|
visible: { type: Boolean, reflect: true },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delay till the tooltip is switched visible.
|
||||||
|
*/
|
||||||
|
delay: { type: Number },
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vertical align of the tooltip.
|
||||||
|
*/
|
||||||
|
valign: { type: String }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.delay = 400;
|
||||||
|
this.valign = 'bottom';
|
||||||
|
this.visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
if (this._showJob) {
|
||||||
|
clearTimeout(this._showJob);
|
||||||
|
this._showJob = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._showJob = setTimeout(() => {
|
||||||
|
this.style.display = 'block';
|
||||||
|
const spacing = parseInt((window.ShadyCSS ? ShadyCSS.getComputedStyleValue(this.target, '--tp-tooltip-spacing') : getComputedStyle(this.target).getPropertyValue('--tp-tooltip-spacing')), 10);
|
||||||
|
setTimeout(() => {
|
||||||
|
this.visible = true;
|
||||||
|
this._posFixed(this.target, this, {
|
||||||
|
valign: this.valign,
|
||||||
|
halign: 'middle',
|
||||||
|
// See: https://github.com/webcomponents/shadycss/issues/83
|
||||||
|
spacing: spacing || 5
|
||||||
|
});
|
||||||
|
}, 10);
|
||||||
|
}, this.delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
hide(cb) {
|
||||||
|
if (this._showJob) {
|
||||||
|
clearTimeout(this._showJob);
|
||||||
|
this._showJob = null;
|
||||||
|
}
|
||||||
|
this.visible = false;
|
||||||
|
setTimeout(() => {
|
||||||
|
cb();
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.customElements.define('tp-tooltip', TpTooltip);
|
Loading…
Reference in New Issue
Block a user