diff --git a/README.md b/README.md
index 1ab27b7..85bb821 100644
--- a/README.md
+++ b/README.md
@@ -1 +1 @@
-# tp-element
+# tp-tooltip
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..91e4bab
--- /dev/null
+++ b/package-lock.json
@@ -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=="
+ }
+ }
+}
diff --git a/package.json b/package.json
index 4ecb195..58b1719 100644
--- a/package.json
+++ b/package.json
@@ -1,18 +1,19 @@
{
- "name": "tp-element",
+ "name": "tp-tooltip",
"version": "0.0.1",
"description": "",
- "main": "tp-element.js",
+ "main": "tp-tooltip.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"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",
"license": "Apache-2.0",
"dependencies": {
+ "@tp/helpers": "^1.0.0",
"lit": "^2.2.0"
}
}
diff --git a/tp-element.js b/tp-element.js
deleted file mode 100644
index 6a92a2f..0000000
--- a/tp-element.js
+++ /dev/null
@@ -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);
diff --git a/tp-tooltip-mixin.js b/tp-tooltip-mixin.js
new file mode 100644
index 0000000..9944cbb
--- /dev/null
+++ b/tp-tooltip-mixin.js
@@ -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
+ *
+ * ```
+ *
+ * @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));
+ }
+ };
+}
diff --git a/tp-tooltip-wrapper.js b/tp-tooltip-wrapper.js
new file mode 100644
index 0000000..393c7c5
--- /dev/null
+++ b/tp-tooltip-wrapper.js
@@ -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
+
+ Content with a tooltip
+
+```
+
+## 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`
+
+ `;
+ }
+
+ 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);
diff --git a/tp-tooltip.js b/tp-tooltip.js
new file mode 100644
index 0000000..193f5e0
--- /dev/null
+++ b/tp-tooltip.js
@@ -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
+
+```
+
+## 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`
+
+ `;
+ }
+
+ 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);