Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(tooltip): fix missing tooltip in consecutive buttons #601

Merged
merged 17 commits into from
Mar 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
b585077
fix(tooltip): add new a test case for row of buttons
wattachai-lseg Feb 22, 2023
b883cb3
fix(tooltip): add native ResizeObserver detection and polyfill fallback
wattachai-lseg Feb 22, 2023
272b499
feat(test-helpers): add frame count param to nextFrame & inNear util
wattachai-lseg Mar 16, 2023
029443f
test(canvas): add wait another frame
wattachai-lseg Mar 16, 2023
0688252
test: fix incorrect param of nextFrame
wattachai-lseg Mar 16, 2023
79d5f2e
test(clock): wait one more frame to complete rendering
wattachai-lseg Mar 16, 2023
62a91e2
test(interactive-chart): add wait for element update & a few more frames
wattachai-lseg Mar 16, 2023
248f30b
test(tab-bar): wait a frame for rendering
wattachai-lseg Mar 16, 2023
e838019
test(tree-select): wait for element update
wattachai-lseg Mar 16, 2023
2af85d5
test(sparkline): wait for element update & a few more frame to comple…
wattachai-lseg Mar 16, 2023
7cbf339
Merge remote-tracking branch 'origin/v6' into fix/missing-tooltip-but…
wattachai-lseg Mar 16, 2023
5441b80
test(led-gauge): fix waiting for element update
wattachai-lseg Mar 17, 2023
24aabd7
test(tornado-chart): fix waiting for element update
wattachai-lseg Mar 17, 2023
acd1ad7
test(tornado-chart): align test file to naming convention
wattachai-lseg Mar 17, 2023
0122125
test(test-helpers): add unit test for replaceWhitespace util
wattachai-lseg Mar 17, 2023
8ace5fd
refactor(test-helpers): combine import statement + descope code cover…
wattachai-lseg Mar 17, 2023
043d737
test: clarity nextFrame usage
wattachai-lseg Mar 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions packages/core/src/elements/ResponsiveElement.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { BasicElement } from './BasicElement.js';
import { ResizeObserver, ResizeObserverEntry } from '@juggle/resize-observer';
// If ResizeObserver native API works fine, this package should be removed in future
import { ResizeObserver as PolyfillResizeObserver } from '@juggle/resize-observer';

export type ElementSize = {
width: number;
Expand Down Expand Up @@ -48,13 +49,21 @@ const triggerResize = (entry: ResizeObserverEntry): void => {
entry.target.dispatchEvent(event);
};

/**
* Trigger Resize all entries from ResizeObserver
* @param entries array of ResizeObserverEntry
* @returns {void}
*/
const entriesResize = (entries: ResizeObserverEntry[]): void => {
entries.forEach(entry => triggerResize(entry));
};

/**
* Global resize observer,
* used to watch changes in element dimensions
*/
const resizeObserver = new ResizeObserver(entries => {
entries.forEach(entry => triggerResize(entry));
});
const resizeObserver = typeof ResizeObserver === 'function' ? new ResizeObserver(entriesResize) : new PolyfillResizeObserver(entriesResize);


/**
* Responsive element base class.
Expand Down
6 changes: 3 additions & 3 deletions packages/elements/src/canvas/__test__/canvas.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe('canvas/Canvas', () => {
Object.defineProperty(window, 'devicePixelRatio', {
value: null
});
await nextFrame();
await nextFrame(2); // wait for resize observer & rendering completion
expect(el.canvas.width).equal(Math.floor(el.width * dpr));
expect(el.canvas.height).equal(Math.floor(el.height * dpr));
});
Expand All @@ -55,7 +55,7 @@ describe('canvas/Canvas', () => {
Object.defineProperty(window, 'devicePixelRatio', {
value: 3
});
await nextFrame();
await nextFrame(2); // wait for resize observer & rendering completion
expect(el.canvas.width).equal(Math.floor(el.width * devicePixelRatio));
expect(el.canvas.height).equal(Math.floor(el.height * devicePixelRatio));
Object.defineProperty(window, 'devicePixelRatio', {
Expand All @@ -70,7 +70,7 @@ describe('canvas/Canvas', () => {

it('Handles fractional pixelation', async () => {
el.style.width = '300.5px';
await elementUpdated();
await elementUpdated(el);
const listener = function () {
el.removeEventListener('resize', listener);
expect(el.style.width, 'ef-canvas\'s width should be fractional').equal('300.5px');
Expand Down
12 changes: 6 additions & 6 deletions packages/elements/src/clock/__test__/clock.analogue.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ describe('clock/Analogue', () => {

it('Shows small size clock when width is less than 130px', async () => {
expect(el.shadowRoot.querySelector('[part="digital"]'), 'digital clock should display inside a default analog clock').not.to.be.null;

// make size smaller than defined break point
el.style.width = '129px';
await elementUpdated(el);
await nextFrame();
await nextFrame(2); // wait for resize observer & rendering completion

expect(el.shadowRoot.querySelector('[part="digital"]'), 'digital clock should not display inside small clock').to.be.null;
expect(el.amPm, 'am-pm should be hidden by default on small clock').to.be.equal(false);
Expand All @@ -63,18 +63,18 @@ describe('clock/Analogue', () => {
el.style.width = '129px';
await elementUpdated(el);
await nextFrame();

// test default behavior
expect(el.hasAttribute('am-pm')).to.be.equal(false);
expect(el.amPm).to.be.equal(false);
expect(el.shadowRoot.querySelector('[part="segment am-pm"]')).to.be.null;

// test when it has am-pm attribute
el = await fixture('<ef-clock analogue am-pm></ef-clock>');
el.style.width = '129px';
await elementUpdated(el);
await nextFrame();

expect(el.amPm, 'amPm property should be true if am-pm attribute is set').to.be.equal(true);
expect(el.shadowRoot.querySelector('[part="segment am-pm"]'), 'AM/PM should display on clock').not.to.be.null;

Expand All @@ -92,7 +92,7 @@ describe('clock/Analogue', () => {
await nextFrame();

expect(el.hasAttribute('size'), 'size attribute should not show if not analog').to.be.equal(false);

el.style.width = '129px';
await elementUpdated(el);
await nextFrame();
Expand Down
2 changes: 1 addition & 1 deletion packages/elements/src/clock/__test__/clock.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('clock/Clock', () => {
el = await fixture('<ef-clock analogue></ef-clock>');
el.style.width = '129px';
await elementUpdated(el);
await nextFrame();
await nextFrame(2); // wait for resize observer & rendering completion

expect(el).shadowDom.to.equalSnapshot();
});
Expand Down
2 changes: 1 addition & 1 deletion packages/elements/src/datetime-field/__test__/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const inputValue = (el) => el.inputValue; // Access private property
const inputElement = (el) => el.inputElement; // Access private property
const focusInput = async (el) => {
await triggerFocusFor(inputElement(el));
await nextFrame(el);
await nextFrame();
};

const arrowRight = async (el) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -833,8 +833,8 @@ describe('interactive-chart/InteractiveChart', () => {

it('Should has dynamic left position in legend when the chart set y axis at left', async () => {
el.config = linePositionLeft;
await elementUpdated();
await nextFrame();
await elementUpdated(el);
await nextFrame(3); // wait for resize observer & rendering completion

expect(el.chart).to.not.be.undefined;
expect(el.chart).to.not.be.null;
Expand All @@ -846,8 +846,8 @@ describe('interactive-chart/InteractiveChart', () => {

it('Should has dynamic left position in legend when the chart set y axis at both edge', async () => {
el.config = twoPriceScales;
await elementUpdated();
await nextFrame();
await elementUpdated(el);
await nextFrame(3); // wait for resize observer & rendering completion

expect(el.chart).to.not.be.undefined;
expect(el.chart).to.not.be.null;
Expand All @@ -859,8 +859,8 @@ describe('interactive-chart/InteractiveChart', () => {

it('Should has fixed left position in legend when the chart set y axis at right edge', async () => {
el.config = line;
await elementUpdated();
await nextFrame();
await elementUpdated(el);
await nextFrame(3); // wait for resize observer & rendering completion

expect(el.chart).to.not.be.undefined;
expect(el.chart).to.not.be.null;
Expand All @@ -873,32 +873,36 @@ describe('interactive-chart/InteractiveChart', () => {
describe('Test deprecated attribute', () => {
it('Switch attribute legendstyle horizontal to vertical, it should display vertical style', async () => {
el = await fixture('<ef-interactive-chart legendstyle="horizontal"></ef-interactive-chart>');

el.config = line;
await elementUpdated();
await elementUpdated(el);
await nextFrame(2); // wait for resize observer & rendering completion

expect(el.chart).to.not.be.undefined;
expect(el.chart).to.not.be.null;

el.setAttribute('legendstyle','vertical');

await nextFrame();
await elementUpdated();
await elementUpdated(el);
expect(el.getAttribute('legend-style')).to.null;
expect(el.shadowRoot.querySelector('[part=legend]').className).to.not.include('horizontal');
});
it('Set legend-style to vertical when legendstyle horizontal, it should display vertical style', async () => {
el = await fixture('<ef-interactive-chart legendstyle="horizontal"></ef-interactive-chart>');

el.config = line;
await elementUpdated();
await elementUpdated(el);
await nextFrame(2); // wait for resize observer & rendering completion

expect(el.chart).to.not.be.undefined;
expect(el.chart).to.not.be.null;
expect(el.getAttribute('legendstyle')).to.equal('horizontal');

el.setAttribute('legend-style','vertical');

await nextFrame();
await elementUpdated();
await elementUpdated(el);
expect(el.shadowRoot.querySelector('[part=legend]').className).to.not.include('horizontal');
});
});
Expand Down
26 changes: 13 additions & 13 deletions packages/elements/src/led-gauge/__test__/led-gauge.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('led-gauge/LedGauge', () => {
el.setAttribute('top-label', 'NewTopLabel');
el.setAttribute('bottom-label', 'NewBottomLabel');

await elementUpdated();
await elementUpdated(el);
top = el.shadowRoot.querySelector('#top');
bottom = el.shadowRoot.querySelector('#bottom');

Expand All @@ -72,7 +72,7 @@ describe('led-gauge/LedGauge', () => {
el.topLabel = 'NewTopLabel';
el.bottomLabel = 'NewBottomLabel';

await elementUpdated();
await elementUpdated(el);
top = el.shadowRoot.querySelector('#top');
bottom = el.shadowRoot.querySelector('#bottom');

Expand All @@ -87,7 +87,7 @@ describe('led-gauge/LedGauge', () => {

el.removeAttribute('top-label');
el.removeAttribute('bottom-label');
await elementUpdated();
await elementUpdated(el);
top = el.shadowRoot.querySelector('#top');
bottom = el.shadowRoot.querySelector('#bottom');

Expand All @@ -111,7 +111,7 @@ describe('led-gauge/LedGauge', () => {

it('Should be able to set topValue and bottomValue via property', async () => {
const el = await fixture(full);
await nextFrame();
await nextFrame(2); // wait for resize observer & rendering completion
top = el.shadowRoot.querySelector('#top');
bottom = el.shadowRoot.querySelector('#bottom');
let topTextPos = parseInt(window.getComputedStyle(top).getPropertyValue('left'), 10);
Expand All @@ -122,7 +122,7 @@ describe('led-gauge/LedGauge', () => {

el.topValue = 50;
el.bottomValue = -50;
await elementUpdated();
await elementUpdated(el);
let newTopTextPos = parseInt(window.getComputedStyle(top).getPropertyValue('left'), 10);
let newBottomTextPos = parseInt(window.getComputedStyle(bottom).getPropertyValue('left'), 10);

Expand All @@ -133,7 +133,7 @@ describe('led-gauge/LedGauge', () => {

it('Should be able to set topValue and bottomValue via attribute', async () => {
const el = await fixture(full);
await nextFrame();
await nextFrame(2); // wait for resize observer & rendering completion
top = el.shadowRoot.querySelector('#top');
bottom = el.shadowRoot.querySelector('#bottom');
let topTextPos = parseInt(window.getComputedStyle(top).getPropertyValue('left'), 10);
Expand All @@ -144,7 +144,7 @@ describe('led-gauge/LedGauge', () => {

el.setAttribute('top-value', '50');
el.setAttribute('bottom-value', '-50');
await elementUpdated();
await elementUpdated(el);
let newTopTextPos = parseInt(window.getComputedStyle(top).getPropertyValue('left'), 10);
let newBottomTextPos = parseInt(window.getComputedStyle(bottom).getPropertyValue('left'), 10);

Expand All @@ -161,7 +161,7 @@ describe('led-gauge/LedGauge', () => {
it('Should update range label when range-label changed by attribute', async () => {
const el = await fixture(rangeFixture);
el.setAttribute('range-label', 'NewRangeLabel');
await elementUpdated();
await elementUpdated(el);
range = el.shadowRoot.querySelector('#range');

expect(range).to.not.equal(null);
Expand All @@ -171,7 +171,7 @@ describe('led-gauge/LedGauge', () => {
it('Should update range label when range-label changed by property', async () => {
const el = await fixture(rangeFixture);
el.rangeLabel = 'NewRangeLabel';
await elementUpdated();
await elementUpdated(el);
range = el.shadowRoot.querySelector('#range');

expect(range).to.not.equal(null);
Expand All @@ -186,7 +186,7 @@ describe('led-gauge/LedGauge', () => {
expect(range).to.not.equal(null);

el.setAttribute('bottom-label', 'Bottom Text');
await elementUpdated();
await elementUpdated(el);
expect(bottom).to.equal(null);
expect(range).to.not.equal(null);
});
Expand All @@ -200,20 +200,20 @@ describe('led-gauge/LedGauge', () => {
it('Should have min=0 and max=100 when set zero=left by property', async () => {
const el = await fixture(zero);
el.zero = 'left';
await elementUpdated();
await elementUpdated(el);
expect(el.zero).to.equal('left');
});

it('Should set zero to center when invalid value is set', async () => {
const el = await fixture(zero);
el.zero = 'left';
await elementUpdated();
await elementUpdated(el);
expect(el.zero).to.equal('left');
expect(el.min).to.equal(0);
expect(el.max).to.equal(100);

el.zero = 'invalid';
await elementUpdated();
await elementUpdated(el);
expect(el.zero).to.equal('center');
expect(el.min).to.equal(-100);
expect(el.max).to.equal(100);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ describe('select/Events', () => {
it('opened-changed event on keyboard pressed', async () => {
const el = await fixture(`<ef-select>${getOptions()}</ef-select>`);
el.focus();
await nextFrame(el);
await nextFrame();
let counter = 0;
let opened = false;

Expand Down
5 changes: 3 additions & 2 deletions packages/elements/src/sparkline/__test__/sparkline.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fixture, expect, elementUpdated } from '@refinitiv-ui/test-helpers';
import { fixture, expect, elementUpdated, nextFrame } from '@refinitiv-ui/test-helpers';

// import element and theme
import '@refinitiv-ui/elements/sparkline';
Expand Down Expand Up @@ -75,7 +75,8 @@ describe('sparkline/Sparkline', () => {
expect(isCanvasBlank(canvas)).to.be.true;

el.data = data;
await elementUpdated();
await elementUpdated(el);
await nextFrame(2); // wait for rendering completion
expect(countDataChanged).to.equal(1);
expect(countDataError).to.equal(0);
expect(isCanvasBlank(canvas)).to.be.false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fixture, expect, elementUpdated, aTimeout } from '@refinitiv-ui/test-helpers';
import { fixture, expect, elementUpdated, aTimeout, nextFrame } from '@refinitiv-ui/test-helpers';

import '@refinitiv-ui/elements/tab-bar';
import '@refinitiv-ui/elemental-theme/light/ef-tab-bar';
Expand Down Expand Up @@ -100,6 +100,7 @@ describe('tab-bar/TabBar', () => {
});

it('Should show only right scroll button', async () => {
await nextFrame(); // wait for resize observer & rendering completion
expect(getElementStyle(leftScrollBtn, 'display')).equal('none');
expect(getElementStyle(rightScrollBtn, 'display')).equal('flex');
});
Expand Down
20 changes: 20 additions & 0 deletions packages/elements/src/tooltip/__demo__/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,26 @@
</custom-style>
</demo-block>

<demo-block layout="normal" header="Tooltip Opening" tags="tooltip, position, show, moving">
side by side buttons: testing tooltip display
<style>
.container {
display: flex;
justify-content: center;

}
.container > ef-button {
height: 50px;
width: 100px;
}
</style>
</div>
<div class="container">
<ef-button title="Hello tooltip1">Tooltip1</ef-button>
<ef-button title="Hello tooltip2">Tooltip2</ef-button>
</div>
</demo-block>

<demo-block layout="normal" header="Transition styles" tags="tooltip, transition">
<div>Tooltip can have different transition styles, which may be overridden by changing `transitionStyle`.</div>
<br/>
Expand Down
Loading