Skip to content

Commit b14bea1

Browse files
committed
refactor: applyTooltipState logic
1 parent e89175c commit b14bea1

File tree

5 files changed

+65
-54
lines changed

5 files changed

+65
-54
lines changed

src/components/tooltip/tooltip-event-controller.ts

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,28 @@ type TooltipCallbacks = {
1010
};
1111

1212
class TooltipController implements ReactiveController {
13-
private readonly _tooltip: IgcTooltipComponent;
13+
private readonly _host: IgcTooltipComponent;
1414
private _anchor: TooltipAnchor;
1515

1616
private _options!: TooltipCallbacks;
1717
private _showTriggers = new Set(['pointerenter']);
1818
private _hideTriggers = new Set(['pointerleave']);
1919

20+
private _open = false;
21+
22+
/** Whether the tooltip is in shown state. */
23+
public get open(): boolean {
24+
return this._open;
25+
}
26+
27+
/** Sets the shown state of the current tooltip. */
28+
public set open(value: boolean) {
29+
this._open = value;
30+
this._open
31+
? service.add(this._host, this._options.onHide)
32+
: service.remove(this._host);
33+
}
34+
2035
/**
2136
* Returns the current tooltip anchor target if any.
2237
*/
@@ -90,9 +105,9 @@ class TooltipController implements ReactiveController {
90105
}
91106

92107
constructor(tooltip: IgcTooltipComponent, options: TooltipCallbacks) {
93-
this._tooltip = tooltip;
108+
this._host = tooltip;
94109
this._options = options;
95-
this._tooltip.addController(this);
110+
this._host.addController(this);
96111
}
97112

98113
private _toggleTriggers(previous: Set<string>, current: Set<string>): void {
@@ -119,29 +134,28 @@ class TooltipController implements ReactiveController {
119134

120135
/** @internal */
121136
public hostConnected(): void {
122-
this._tooltip.addEventListener('pointerenter', this);
123-
this._tooltip.addEventListener('pointerleave', this);
137+
this._host.addEventListener('pointerenter', this);
138+
this._host.addEventListener('pointerleave', this);
124139
}
125140

126141
/** @internal */
127142
public hostDisconnected(): void {
128-
// console.log('disconnected callback');
129-
this._tooltip.hide();
130-
service.remove(this._tooltip);
131-
this._tooltip.removeEventListener('pointerenter', this);
132-
this._tooltip.removeEventListener('pointerleave', this);
143+
this._dispose();
144+
service.remove(this._host);
145+
this._host.removeEventListener('pointerenter', this);
146+
this._host.removeEventListener('pointerleave', this);
133147
}
134148

135149
/** @internal */
136150
public handleEvent(event: Event): void {
137151
// Tooltip handlers
138-
if (event.target === this._tooltip) {
152+
if (event.target === this._host) {
139153
switch (event.type) {
140154
case 'pointerenter':
141-
this._options.onShow.call(this._tooltip, event);
155+
this._options.onShow.call(this._host, event);
142156
break;
143157
case 'pointerleave':
144-
this._options.onHide.call(this._tooltip, event);
158+
this._options.onHide.call(this._host, event);
145159
break;
146160
default:
147161
return;
@@ -151,11 +165,11 @@ class TooltipController implements ReactiveController {
151165
// Anchor handlers
152166
if (event.target === this._anchor) {
153167
if (this._showTriggers.has(event.type)) {
154-
this._options.onShow.call(this._tooltip, event);
168+
this._options.onShow.call(this._host, event);
155169
}
156170

157171
if (this._hideTriggers.has(event.type)) {
158-
this._options.onHide.call(this._tooltip, event);
172+
this._options.onHide.call(this._host, event);
159173
}
160174
}
161175
}

src/components/tooltip/tooltip-service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class TooltipEscapeCallbacks {
99
private _collection = new Map<IgcTooltipComponent, TooltipHideCallback>();
1010

1111
private _setListener(state = true): void {
12+
/* c8 ignore next 3 */
1213
if (isServer) {
1314
return;
1415
}

src/components/tooltip/tooltip.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ describe('Tooltip', () => {
615615
);
616616
expect(eventSpy.secondCall).calledWith(
617617
state.open ? 'igcOpened' : 'igcClosed',
618-
{ detail: anchor }
618+
{ cancelable: false, detail: anchor }
619619
);
620620
};
621621

src/components/tooltip/tooltip.ts

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import { styles as shared } from './themes/shared/tooltip.common.css';
1717
import { all } from './themes/themes.js';
1818
import { styles } from './themes/tooltip.base.css.js';
1919
import { addTooltipController } from './tooltip-event-controller.js';
20-
import service from './tooltip-service.js';
2120

2221
export interface IgcTooltipComponentEventMap {
2322
igcOpening: CustomEvent<Element | null>;
@@ -77,7 +76,6 @@ export default class IgcTooltipComponent extends EventEmitterMixin<
7776
});
7877

7978
private _timeoutId?: number;
80-
private _open = false;
8179
private _showDelay = 200;
8280
private _hideDelay = 300;
8381

@@ -92,14 +90,11 @@ export default class IgcTooltipComponent extends EventEmitterMixin<
9290
*/
9391
@property({ type: Boolean, reflect: true })
9492
public set open(value: boolean) {
95-
this._open = value;
96-
this._open
97-
? service.add(this, this._hideOnInteraction)
98-
: service.remove(this);
93+
this._controller.open = value;
9994
}
10095

10196
public get open(): boolean {
102-
return this._open;
97+
return this._controller.open;
10398
}
10499

105100
/**
@@ -254,57 +249,55 @@ export default class IgcTooltipComponent extends EventEmitterMixin<
254249
this._controller.anchor = target;
255250
}
256251

252+
private _emitEvent(name: keyof IgcTooltipComponentEventMap): boolean {
253+
return this.emitEvent(name, {
254+
cancelable: name === 'igcOpening' || name === 'igcClosing',
255+
detail: this._controller.anchor,
256+
});
257+
}
258+
257259
private async _applyTooltipState({
258260
show,
259261
withDelay = false,
260262
withEvents = false,
261263
}: TooltipStateOptions): Promise<boolean> {
262-
if (show === this.open) return false;
263-
264-
const delay = show ? this.showDelay : this.hideDelay;
265-
266-
if (withEvents) {
267-
const eventName = show ? 'igcOpening' : 'igcClosing';
268-
const allowed = this.emitEvent(eventName, {
269-
cancelable: true,
270-
detail: this._controller.anchor,
271-
});
264+
if (show === this.open) {
265+
return false;
266+
}
272267

273-
if (!allowed) return false;
268+
if (withEvents && !this._emitEvent(show ? 'igcOpening' : 'igcClosing')) {
269+
return false;
274270
}
275271

276-
const _commitStateChange = async () => {
272+
const commitStateChange = async (): Promise<boolean> => {
277273
if (show) {
278274
this.open = true;
279275
}
280276

281-
const result = await this._player.playExclusive(
277+
const animationComplete = await this._player.playExclusive(
282278
show ? this._showAnimation : this._hideAnimation
283279
);
284-
this.open = result ? show : !show;
285280

286-
if (!result) {
287-
return false;
288-
}
281+
this.open = show;
289282

290-
if (withEvents) {
291-
const eventName = show ? 'igcOpened' : 'igcClosed';
292-
this.emitEvent(eventName, { detail: this._controller.anchor });
283+
if (animationComplete && withEvents) {
284+
this._emitEvent(show ? 'igcOpened' : 'igcClosed');
293285
}
294286

295-
return result;
287+
return animationComplete;
296288
};
297289

298290
if (withDelay) {
299291
clearTimeout(this._timeoutId);
300-
return new Promise((resolve) => {
301-
this._timeoutId = setTimeout(() => {
302-
_commitStateChange().then(resolve);
303-
}, delay);
292+
return new Promise(() => {
293+
this._timeoutId = setTimeout(
294+
async () => await commitStateChange(),
295+
show ? this.showDelay : this.hideDelay
296+
);
304297
});
305298
}
306299

307-
return _commitStateChange();
300+
return commitStateChange();
308301
}
309302

310303
/** Shows the tooltip if not already showing. */

stories/tooltip.stories.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -334,16 +334,19 @@ export const Default: Story = {
334334
`,
335335
};
336336

337-
let tooltip!: IgcTooltipComponent;
338-
339337
function createDynamicTooltip() {
340-
tooltip ??= document.createElement('igc-tooltip');
338+
const tooltip = document.createElement('igc-tooltip');
341339
tooltip.message = `I'm created on demand at ${new Date().toLocaleTimeString()}`;
342340
tooltip.anchor = 'dynamic-target';
343341
tooltip.id = 'dynamic';
344342

345-
tooltip.addEventListener('igcClosed', () => tooltip.remove());
346-
document.body.appendChild(tooltip);
343+
const previousTooltip = document.querySelector('#dynamic');
344+
const target = document.querySelector('#dynamic-target')!;
345+
346+
previousTooltip
347+
? previousTooltip.replaceWith(tooltip)
348+
: target.after(tooltip);
349+
347350
tooltip.show();
348351
}
349352

0 commit comments

Comments
 (0)