Skip to content

Commit 32472c3

Browse files
committed
Avoids hiding on click of popover
1 parent 10e60b7 commit 32472c3

File tree

1 file changed

+66
-61
lines changed
  • src/webviews/apps/shared/components/overlays

1 file changed

+66
-61
lines changed

src/webviews/apps/shared/components/overlays/popover.ts

Lines changed: 66 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ export class GlPopover extends GlElement {
223223
document.removeEventListener('focusin', this.handlePopupBlur);
224224
window.removeEventListener('webview-blur', this.handleWebviewBlur, false);
225225
document.removeEventListener('keydown', this.handleDocumentKeyDown);
226+
document.removeEventListener('mousedown', this.handleWebviewMouseDown);
227+
super.disconnectedCallback();
226228
}
227229

228230
override firstUpdated() {
@@ -235,6 +237,64 @@ export class GlPopover extends GlElement {
235237
}
236238
}
237239

240+
override render() {
241+
return html`<sl-popup
242+
part="base"
243+
exportparts="
244+
popup:base__popup,
245+
arrow:base__arrow
246+
"
247+
class="popover"
248+
.anchor=${this.anchor}
249+
placement=${this.placement}
250+
distance=${this.distance}
251+
skidding=${this.skidding}
252+
strategy=${this.hoist ? 'fixed' : 'absolute'}
253+
auto-size="horizontal"
254+
auto-size-padding="3"
255+
flip-padding="3"
256+
flip
257+
shift
258+
?arrow=${this.arrow}
259+
hover-bridge
260+
>
261+
<div slot="anchor" aria-describedby="popover">
262+
<slot name="anchor"></slot>
263+
</div>
264+
265+
<div
266+
part="body"
267+
id="popover"
268+
class="popover__body"
269+
role="tooltip"
270+
aria-live=${this.open ? 'polite' : 'off'}
271+
>
272+
<slot name="content"></slot>
273+
</div>
274+
</sl-popup>`;
275+
}
276+
277+
private _triggeredBy: TriggerType | undefined;
278+
/** Shows the popover. */
279+
async show(triggeredBy?: TriggerType) {
280+
if (this._triggeredBy == null || triggeredBy !== 'hover') {
281+
this._triggeredBy = triggeredBy;
282+
}
283+
if (this.open) return undefined;
284+
285+
this.open = true;
286+
return waitForEvent(this, 'gl-popover-after-show');
287+
}
288+
289+
/** Hides the popover */
290+
async hide() {
291+
this._triggeredBy = undefined;
292+
if (!this.open) return undefined;
293+
294+
this.open = false;
295+
return waitForEvent(this, 'gl-popover-after-hide');
296+
}
297+
238298
private handleTriggerBlur = (e: FocusEvent) => {
239299
if (this.open && this.hasTrigger('focus')) {
240300
if (e.relatedTarget && this.contains(e.relatedTarget as Node)) return;
@@ -243,14 +303,17 @@ export class GlPopover extends GlElement {
243303
}
244304
};
245305

246-
private handleTriggerClick = () => {
306+
private handleTriggerClick = (e: MouseEvent) => {
247307
if (this.hasTrigger('click')) {
248308
if (this.open && this._triggeredBy !== 'hover') {
249309
if (this._skipHideOnClick) {
250310
this._skipHideOnClick = false;
251311
return;
252312
}
253313

314+
const composedPath = e.composedPath();
315+
if (composedPath.includes(this.body)) return;
316+
254317
void this.hide();
255318
} else {
256319
void this.show('click');
@@ -287,7 +350,7 @@ export class GlPopover extends GlElement {
287350

288351
private handlePopupBlur = (e: FocusEvent) => {
289352
const composedPath = e.composedPath();
290-
if (!composedPath.includes(this)) {
353+
if (!composedPath.includes(this) && !composedPath.includes(this.body)) {
291354
void this.hide();
292355
}
293356
};
@@ -298,7 +361,7 @@ export class GlPopover extends GlElement {
298361

299362
private handleWebviewMouseDown = (e: MouseEvent) => {
300363
const composedPath = e.composedPath();
301-
if (!composedPath.includes(this)) {
364+
if (!composedPath.includes(this) && !composedPath.includes(this.body)) {
302365
void this.hide();
303366
}
304367
};
@@ -394,62 +457,4 @@ export class GlPopover extends GlElement {
394457
void this.hide();
395458
}
396459
}
397-
398-
private _triggeredBy: TriggerType | undefined;
399-
/** Shows the popover. */
400-
async show(triggeredBy?: TriggerType) {
401-
if (this._triggeredBy == null || triggeredBy !== 'hover') {
402-
this._triggeredBy = triggeredBy;
403-
}
404-
if (this.open) return undefined;
405-
406-
this.open = true;
407-
return waitForEvent(this, 'gl-popover-after-show');
408-
}
409-
410-
/** Hides the popover */
411-
async hide() {
412-
this._triggeredBy = undefined;
413-
if (!this.open) return undefined;
414-
415-
this.open = false;
416-
return waitForEvent(this, 'gl-popover-after-hide');
417-
}
418-
419-
override render() {
420-
return html`<sl-popup
421-
part="base"
422-
exportparts="
423-
popup:base__popup,
424-
arrow:base__arrow
425-
"
426-
class="popover"
427-
.anchor=${this.anchor}
428-
placement=${this.placement}
429-
distance=${this.distance}
430-
skidding=${this.skidding}
431-
strategy=${this.hoist ? 'fixed' : 'absolute'}
432-
auto-size="horizontal"
433-
auto-size-padding="3"
434-
flip-padding="3"
435-
flip
436-
shift
437-
?arrow=${this.arrow}
438-
hover-bridge
439-
>
440-
<div slot="anchor" aria-describedby="popover">
441-
<slot name="anchor"></slot>
442-
</div>
443-
444-
<div
445-
part="body"
446-
id="popover"
447-
class="popover__body"
448-
role="tooltip"
449-
aria-live=${this.open ? 'polite' : 'off'}
450-
>
451-
<slot name="content"></slot>
452-
</div>
453-
</sl-popup>`;
454-
}
455460
}

0 commit comments

Comments
 (0)