Convert gr-tooltip to lit-element
Change-Id: I5d3a9d12514998eaf28e0bacd6b4f5836dc1c557
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.ts b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.ts
index 0585aec8..4315071 100644
--- a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.ts
+++ b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.ts
@@ -210,13 +210,9 @@
const left = rect.left - parentRect.left + (rect.width - boxRect.width) / 2;
const right = parentRect.width - left - boxRect.width;
if (left < 0) {
- tooltip.updateStyles({
- '--gr-tooltip-arrow-center-offset': `${left}px`,
- });
+ tooltip.arrowCenterOffset = `${left}px`;
} else if (right < 0) {
- tooltip.updateStyles({
- '--gr-tooltip-arrow-center-offset': `${-0.5 * right}px`,
- });
+ tooltip.arrowCenterOffset = `${-0.5 * right}px`;
}
tooltip.style.left = `${Math.max(0, left)}px`;
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.js b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.js
index 8d3bbb0..98ba237 100644
--- a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.js
@@ -25,8 +25,8 @@
function makeTooltip(tooltipRect, parentRect) {
return {
+ arrowCenterOffset: '0',
getBoundingClientRect() { return tooltipRect; },
- updateStyles: sinon.stub(),
style: {left: 0, top: 0},
parentElement: {
getBoundingClientRect() { return parentRect; },
@@ -66,12 +66,12 @@
{top: 0, left: 0, width: 1000});
element._positionTooltip(tooltip);
- assert.isFalse(tooltip.updateStyles.called);
+ assert.equal(tooltip.arrowCenterOffset, '0');
assert.equal(tooltip.style.left, '175px');
assert.equal(tooltip.style.top, '100px');
});
- test('left side position', () => {
+ test('left side position', async () => {
sinon.stub(element, 'getBoundingClientRect').callsFake(() => {
return {top: 100, left: 10, width: 50};
});
@@ -80,10 +80,8 @@
{top: 0, left: 0, width: 1000});
element._positionTooltip(tooltip);
- assert.isTrue(tooltip.updateStyles.called);
- const offset = tooltip.updateStyles
- .lastCall.args[0]['--gr-tooltip-arrow-center-offset'];
- assert.isBelow(parseFloat(offset.replace(/px$/, '')), 0);
+ await element.updateComplete;
+ assert.isBelow(parseFloat(tooltip.arrowCenterOffset.replace(/px$/, '')), 0);
assert.equal(tooltip.style.left, '0px');
assert.equal(tooltip.style.top, '100px');
});
@@ -97,10 +95,7 @@
{top: 0, left: 0, width: 1000});
element._positionTooltip(tooltip);
- assert.isTrue(tooltip.updateStyles.called);
- const offset = tooltip.updateStyles
- .lastCall.args[0]['--gr-tooltip-arrow-center-offset'];
- assert.isAbove(parseFloat(offset.replace(/px$/, '')), 0);
+ assert.isAbove(parseFloat(tooltip.arrowCenterOffset.replace(/px$/, '')), 0);
assert.equal(tooltip.style.left, '915px');
assert.equal(tooltip.style.top, '100px');
});
@@ -115,19 +110,16 @@
element.positionBelow = true;
element._positionTooltip(tooltip);
- assert.isTrue(tooltip.updateStyles.called);
- const offset = tooltip.updateStyles
- .lastCall.args[0]['--gr-tooltip-arrow-center-offset'];
- assert.isAbove(parseFloat(offset.replace(/px$/, '')), 0);
+ assert.isAbove(parseFloat(tooltip.arrowCenterOffset.replace(/px$/, '')), 0);
assert.equal(tooltip.style.left, '915px');
assert.equal(tooltip.style.top, '157.2px');
});
test('hides tooltip when detached', async () => {
- sinon.stub(element, '_handleHideTooltip');
+ const handleHideTooltipStub = sinon.stub(element, '_handleHideTooltip');
element.remove();
await element.updateComplete;
- assert.isTrue(element._handleHideTooltip.called);
+ assert.isTrue(handleHideTooltipStub.called);
});
test('sets up listeners when has-tooltip is changed', async () => {
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip.ts b/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip.ts
index cab05b4..0e41891 100644
--- a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip.ts
+++ b/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip.ts
@@ -14,14 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import '../../../styles/shared-styles';
-import {PolymerElement} from '@polymer/polymer/polymer-element';
-import {htmlTemplate} from './gr-tooltip_html';
-import {customElement, property, observe} from '@polymer/decorators';
-export interface GrTooltip {
- $: {};
-}
+import {sharedStyles} from '../../../styles/shared-styles';
+import {LitElement, css, html} from 'lit';
+import {customElement, property} from 'lit/decorators';
+import {styleMap} from 'lit/directives/style-map';
declare global {
interface HTMLElementTagNameMap {
@@ -30,22 +27,78 @@
}
@customElement('gr-tooltip')
-export class GrTooltip extends PolymerElement {
- static get template() {
- return htmlTemplate;
- }
-
+export class GrTooltip extends LitElement {
@property({type: String})
text = '';
@property({type: String})
maxWidth = '';
- @property({type: Boolean, reflectToAttribute: true})
+ @property({type: String})
+ arrowCenterOffset = '0';
+
+ @property({type: Boolean, reflect: true, attribute: 'position-below'})
positionBelow = false;
- @observe('maxWidth')
- _updateWidth(maxWidth: string) {
- this.updateStyles({'--tooltip-max-width': maxWidth});
+ static override get styles() {
+ return [
+ sharedStyles,
+ css`
+ :host {
+ --gr-tooltip-arrow-size: 0.5em;
+
+ background-color: var(--tooltip-background-color);
+ box-shadow: var(--elevation-level-2);
+ color: var(--tooltip-text-color);
+ font-size: var(--font-size-small);
+ position: absolute;
+ z-index: 1000;
+ }
+ :host .tooltip {
+ padding: var(--spacing-m) var(--spacing-l);
+ }
+ :host .arrowPositionBelow,
+ :host([position-below]) .arrowPositionAbove {
+ display: none;
+ }
+ :host([position-below]) .arrowPositionBelow {
+ display: initial;
+ }
+ .arrow {
+ border-left: var(--gr-tooltip-arrow-size) solid transparent;
+ border-right: var(--gr-tooltip-arrow-size) solid transparent;
+ height: 0;
+ position: absolute;
+ left: calc(50% - var(--gr-tooltip-arrow-size));
+ width: 0;
+ }
+ .arrowPositionAbove {
+ border-top: var(--gr-tooltip-arrow-size) solid
+ var(--tooltip-background-color);
+ bottom: calc(-1 * var(--gr-tooltip-arrow-size));
+ }
+ .arrowPositionBelow {
+ border-bottom: var(--gr-tooltip-arrow-size) solid
+ var(--tooltip-background-color);
+ top: calc(-1 * var(--gr-tooltip-arrow-size));
+ }
+ `,
+ ];
+ }
+
+ override render() {
+ this.style.maxWidth = this.maxWidth;
+
+ return html` <div class="tooltip">
+ <i
+ class="arrowPositionBelow arrow"
+ style="${styleMap({marginLeft: this.arrowCenterOffset})}"
+ ></i>
+ ${this.text}
+ <i
+ class="arrowPositionAbove arrow"
+ style="${styleMap({marginLeft: this.arrowCenterOffset})}"
+ ></i>
+ </div>`;
}
}
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_html.ts b/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_html.ts
deleted file mode 100644
index d59a6c3..0000000
--- a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_html.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @license
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {html} from '@polymer/polymer/lib/utils/html-tag';
-
-export const htmlTemplate = html`
- <style include="shared-styles">
- :host {
- --gr-tooltip-arrow-size: 0.5em;
- --gr-tooltip-arrow-center-offset: 0;
-
- background-color: var(--tooltip-background-color);
- box-shadow: var(--elevation-level-2);
- color: var(--tooltip-text-color);
- font-size: var(--font-size-small);
- position: absolute;
- z-index: 1000;
- max-width: var(--tooltip-max-width);
- }
- :host .tooltip {
- padding: var(--spacing-m) var(--spacing-l);
- }
- :host .arrowPositionBelow,
- :host([position-below]) .arrowPositionAbove {
- display: none;
- }
- :host([position-below]) .arrowPositionBelow {
- display: initial;
- }
- .arrow {
- border-left: var(--gr-tooltip-arrow-size) solid transparent;
- border-right: var(--gr-tooltip-arrow-size) solid transparent;
- height: 0;
- position: absolute;
- left: calc(50% - var(--gr-tooltip-arrow-size));
- margin-left: var(--gr-tooltip-arrow-center-offset);
- width: 0;
- }
- .arrowPositionAbove {
- border-top: var(--gr-tooltip-arrow-size) solid
- var(--tooltip-background-color);
- bottom: calc(-1 * var(--gr-tooltip-arrow-size));
- }
- .arrowPositionBelow {
- border-bottom: var(--gr-tooltip-arrow-size) solid
- var(--tooltip-background-color);
- top: calc(-1 * var(--gr-tooltip-arrow-size));
- }
- </style>
- <div class="tooltip">
- <i class="arrowPositionBelow arrow"></i>
- [[text]]
- <i class="arrowPositionAbove arrow"></i>
- </div>
-`;
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.ts b/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.ts
index 8b44047..b693a9e 100644
--- a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.ts
@@ -17,49 +17,45 @@
import '../../../test/common-test-setup-karma';
import './gr-tooltip';
-import {html} from '@polymer/polymer/lib/utils/html-tag';
import {GrTooltip} from './gr-tooltip';
+import {queryAndAssert} from '../../../test/test-utils';
-const basicFixture = fixtureFromTemplate(html` <gr-tooltip> </gr-tooltip> `);
+const basicFixture = fixtureFromElement('gr-tooltip');
suite('gr-tooltip tests', () => {
let element: GrTooltip;
- setup(() => {
+
+ setup(async () => {
element = basicFixture.instantiate() as GrTooltip;
+ await element.updateComplete;
});
- test('max-width is respected if set', () => {
+ test('max-width is respected if set', async () => {
element.text =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit' +
', sed do eiusmod tempor incididunt ut labore et dolore magna aliqua';
element.maxWidth = '50px';
+ await element.updateComplete;
assert.equal(getComputedStyle(element).width, '50px');
});
- test('the correct arrow is displayed', () => {
+ test('the correct arrow is displayed', async () => {
assert.equal(
- getComputedStyle(
- element.shadowRoot!.querySelector('.arrowPositionBelow')!
- ).display,
+ getComputedStyle(queryAndAssert(element, '.arrowPositionBelow')!).display,
'none'
);
assert.notEqual(
- getComputedStyle(
- element.shadowRoot!.querySelector('.arrowPositionAbove')!
- ).display,
+ getComputedStyle(queryAndAssert(element, '.arrowPositionAbove')!).display,
'none'
);
element.positionBelow = true;
+ await element.updateComplete;
assert.notEqual(
- getComputedStyle(
- element.shadowRoot!.querySelector('.arrowPositionBelow')!
- ).display,
+ getComputedStyle(queryAndAssert(element, '.arrowPositionBelow')!).display,
'none'
);
assert.equal(
- getComputedStyle(
- element.shadowRoot!.querySelector('.arrowPositionAbove')!
- ).display,
+ getComputedStyle(queryAndAssert(element, '.arrowPositionAbove')!).display,
'none'
);
});