Skip to content

Commit 4e64ee2

Browse files
authored
feat(tile-manager): Added transition for UI triggered maximized state changes (#1624)
* Updated tests to wait for said transition when applicable * Changed icon service test to wait on macrotask queue since tests were flaky.
1 parent 844c217 commit 4e64ee2

File tree

5 files changed

+106
-94
lines changed

5 files changed

+106
-94
lines changed

src/components/common/controllers/drag.ts

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ type State = {
2727
position: { x: number; y: number };
2828
offset: { x: number; y: number };
2929
pointerState: {
30-
initial: { initialX: number; initialY: number };
31-
current: { currentX: number; currentY: number };
30+
previous: { x: number; y: number };
31+
current: { x: number; y: number };
3232
direction: Direction;
3333
};
3434
};
@@ -169,30 +169,13 @@ class DragController implements ReactiveController {
169169
}
170170

171171
private get _stateParameters(): DragState {
172-
this._state.pointerState.direction = this._trackPointerMovement();
173-
174172
return {
175173
...this._state,
176174
ghost: this._ghost,
177175
element: this._matchedElement,
178176
};
179177
}
180178

181-
private _trackPointerMovement(): Direction {
182-
const { initialX, initialY } = this._state.pointerState.initial;
183-
const { currentX, currentY } = this._state.pointerState.current;
184-
const deltaX = currentX - initialX;
185-
const deltaY = currentY - initialY;
186-
const LTR = isLTR(this._host);
187-
188-
const isHorizontalMove = Math.abs(deltaX) >= Math.abs(deltaY);
189-
190-
if (isHorizontalMove) {
191-
return (LTR ? deltaX >= 0 : deltaX <= 0) ? 'end' : 'start';
192-
}
193-
return deltaY >= 0 ? 'bottom' : 'top';
194-
}
195-
196179
constructor(
197180
host: ReactiveControllerHost & LitElement,
198181
options?: DragControllerConfiguration
@@ -298,17 +281,9 @@ class DragController implements ReactiveController {
298281
}
299282

300283
this._updatePosition(event);
284+
this._updatePointerState(event);
301285
this._updateMatcher(event);
302286

303-
this._state.pointerState.initial = {
304-
initialX: this._state.pointerState.current.currentX,
305-
initialY: this._state.pointerState.current.currentY,
306-
};
307-
this._state.pointerState.current = {
308-
currentX: event.clientX,
309-
currentY: event.clientY,
310-
};
311-
312287
const parameters = {
313288
event,
314289
state: this._stateParameters,
@@ -360,8 +335,8 @@ class DragController implements ReactiveController {
360335
position,
361336
offset,
362337
pointerState: {
363-
initial: { initialX: clientX, initialY: clientY },
364-
current: { currentX: clientX, currentY: clientY },
338+
previous: { x: clientX, y: clientY },
339+
current: { x: clientX, y: clientY },
365340
direction: 'end',
366341
},
367342
};
@@ -434,7 +409,24 @@ class DragController implements ReactiveController {
434409
const posX = this._hasSnapping ? clientX - layerX : clientX - layerX + x;
435410
const posY = this._hasSnapping ? clientY - layerY : clientY - layerY + y;
436411

437-
Object.assign(this._state.position, { x: posX, y: posY });
412+
this._state.position = { x: posX, y: posY };
413+
}
414+
415+
private _updatePointerState({ clientX, clientY }: PointerEvent): void {
416+
const state = this._state.pointerState;
417+
418+
state.previous = { ...state.current };
419+
state.current = { x: clientX, y: clientY };
420+
421+
const dx = state.current.x - state.previous.x;
422+
const dy = state.current.y - state.previous.y;
423+
424+
if (Math.abs(dx) >= Math.abs(dy)) {
425+
const swapHorizontal = isLTR(this._host) ? dx >= 0 : dx <= 0;
426+
state.direction = swapHorizontal ? 'end' : 'start';
427+
} else {
428+
state.direction = dy >= 0 ? 'bottom' : 'top';
429+
}
438430
}
439431

440432
private _assignPosition(element: HTMLElement): void {

src/components/icon/icon.spec.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
expect,
55
fixture,
66
html,
7-
nextFrame,
87
} from '@open-wc/testing';
98
import { stub } from 'sinon';
109

@@ -163,7 +162,7 @@ describe('Icon broadcast service', () => {
163162
const iconName = 'bug';
164163

165164
registerIconFromText(iconName, bugSvg, collectionName);
166-
await nextFrame();
165+
await aTimeout(0);
167166

168167
const { actionType, collections } = first(events).data;
169168
expect(actionType).to.equal(ActionType.RegisterIcon);
@@ -183,7 +182,7 @@ describe('Icon broadcast service', () => {
183182
for (const each of icons) {
184183
registerIconFromText(each[0], each[1], collectionName);
185184
}
186-
await nextFrame();
185+
await aTimeout(0);
187186

188187
expect(events).lengthOf(icons.length);
189188
for (const [idx, event] of events.entries()) {
@@ -207,7 +206,7 @@ describe('Icon broadcast service', () => {
207206
name: 'reference-test',
208207
collection: collectionName,
209208
});
210-
await nextFrame();
209+
await aTimeout(0);
211210

212211
const { actionType, collections, references } = last(events).data;
213212

@@ -227,7 +226,7 @@ describe('Icon broadcast service', () => {
227226
meta.name = 'reference-test';
228227
meta.collection = collectionName;
229228
setIconRef(refName, refCollectionName, meta);
230-
await nextFrame();
229+
await aTimeout(0);
231230

232231
const { actionType, collections, references } = last(events).data;
233232

@@ -250,7 +249,7 @@ describe('Icon broadcast service', () => {
250249
},
251250
overwrite: true,
252251
});
253-
await nextFrame();
252+
await aTimeout(0);
254253

255254
expect(events.length).to.equal(0);
256255
});
@@ -286,7 +285,7 @@ describe('Icon broadcast service', () => {
286285

287286
// a peer is requesting a state sync
288287
channel.postMessage({ actionType: ActionType.SyncState });
289-
await nextFrame();
288+
await aTimeout(0);
290289

291290
expect(events).lengthOf(2); // [ActionType.RegisterIcon, ActionType.SyncState]
292291

@@ -311,7 +310,7 @@ describe('Icon broadcast service', () => {
311310

312311
// a peer is requesting a state sync
313312
channel.postMessage({ actionType: ActionType.SyncState });
314-
await nextFrame();
313+
await aTimeout(0);
315314

316315
expect(events).lengthOf(1); // [ActionType.SyncState]
317316

src/components/tile-manager/tile-dnd.spec.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -529,14 +529,16 @@ describe('Tile drag and drop', () => {
529529
const [maximize, _] = getActionButtons(tile);
530530
const eventSpy = spy(tile, 'emitEvent');
531531

532+
// Wait for maximized transition trigger from UI
532533
maximize.click();
533-
await elementUpdated(tile);
534+
await viewTransitionComplete();
534535

535536
expect(tile.maximized).to.be.true;
536537
expect(eventSpy).not.calledWith('igcTileDragStart');
537538

539+
// Wait for maximized transition trigger from UI
538540
maximize.click();
539-
await elementUpdated(tile);
541+
await viewTransitionComplete();
540542

541543
expect(tile.maximized).to.be.false;
542544
});
@@ -547,14 +549,16 @@ describe('Tile drag and drop', () => {
547549
const [maximize, _] = getActionButtons(tile);
548550
const eventSpy = spy(tile, 'emitEvent');
549551

552+
// Wait for maximized transition trigger from UI
550553
maximize.click();
551-
await elementUpdated(tile);
554+
await viewTransitionComplete();
552555

553556
expect(tile.maximized).to.be.true;
554557
expect(eventSpy).not.calledWith('igcTileDragStart');
555558

559+
// Wait for maximized transition trigger from UI
556560
maximize.click();
557-
await elementUpdated(tile);
561+
await viewTransitionComplete();
558562

559563
expect(tile.maximized).to.be.false;
560564
});

src/components/tile-manager/tile-manager.spec.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
1+
import {
2+
elementUpdated,
3+
expect,
4+
fixture,
5+
html,
6+
nextFrame,
7+
} from '@open-wc/testing';
28
import { range } from 'lit/directives/range.js';
39
import { match, restore, spy, stub } from 'sinon';
410
import IgcIconButtonComponent from '../button/icon-button.js';
@@ -15,6 +21,11 @@ describe('Tile Manager component', () => {
1521

1622
let tileManager: IgcTileManagerComponent;
1723

24+
async function viewTransitionComplete() {
25+
await nextFrame();
26+
await nextFrame();
27+
}
28+
1829
function getTileManagerBase() {
1930
return tileManager.renderRoot.querySelector<HTMLElement>('[part="base"]')!;
2031
}
@@ -635,18 +646,19 @@ describe('Tile Manager component', () => {
635646
const eventSpy = spy(tile, 'emitEvent');
636647
const btnMaximize = getActionButtons(tile)[0];
637648

649+
// Wait for maximized transition trigger from UI
638650
simulateClick(btnMaximize);
639-
await elementUpdated(tile);
640-
await elementUpdated(tileManager);
651+
await viewTransitionComplete();
641652

642653
expect(eventSpy).calledWith('igcTileMaximize', {
643654
detail: { tile: tile, state: true },
644655
cancelable: true,
645656
});
646657
expect(tile.maximized).to.be.true;
647658

659+
// Wait for maximized transition trigger from UI
648660
simulateClick(btnMaximize);
649-
await elementUpdated(tileManager);
661+
await viewTransitionComplete();
650662

651663
expect(eventSpy).to.have.been.calledTwice;
652664
expect(eventSpy).calledWith('igcTileMaximize', {
@@ -678,8 +690,10 @@ describe('Tile Manager component', () => {
678690
const btnMaximize = getActionButtons(tile)[0];
679691

680692
expect(btnMaximize.name).equals('expand_content');
693+
694+
// Wait for maximized transition trigger from UI
681695
simulateClick(btnMaximize);
682-
await elementUpdated(tileManager);
696+
await viewTransitionComplete();
683697

684698
expect(btnMaximize.name).equals('collapse_content');
685699

0 commit comments

Comments
 (0)