Skip to content

Commit ba0212f

Browse files
committed
Use tippy.js for context popup
By appending the tooltips to document.body, we can avoid any stacking context issues caused by surrounding element's CSS. I wasn't able to get this portalling to work with Fomantic popups, so this uses tippy.js instead of Fomantic popups. We should aim to replace all Fomantic popups with this eventually. Fixes: #20377
1 parent 17ce5f8 commit ba0212f

File tree

5 files changed

+131
-11
lines changed

5 files changed

+131
-11
lines changed

Diff for: package-lock.json

+31
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"pretty-ms": "7.0.1",
3030
"sortablejs": "1.15.0",
3131
"swagger-ui-dist": "4.11.1",
32+
"tippy.js": "6.3.7",
3233
"tributejs": "5.1.3",
3334
"uint8-to-base64": "0.2.0",
3435
"vue": "2.6.14",

Diff for: web_src/js/features/contextpopup.js

+11-11
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import $ from 'jquery';
22
import Vue from 'vue';
33
import ContextPopup from '../components/ContextPopup.vue';
44
import {parseIssueHref} from '../utils.js';
5+
import tippy from 'tippy.js';
56

67
export default function initContextPopups() {
78
const refIssues = $('.ref-issue');
@@ -16,7 +17,6 @@ export default function initContextPopups() {
1617
if (!owner) return;
1718

1819
const el = document.createElement('div');
19-
el.className = 'ui custom popup hidden';
2020
el.innerHTML = '<div></div>';
2121
this.parentNode.insertBefore(el, this.nextSibling);
2222

@@ -33,17 +33,17 @@ export default function initContextPopups() {
3333
el.textContent = 'ContextPopup failed to load';
3434
}
3535

36-
$(this).popup({
37-
variation: 'wide',
38-
delay: {
39-
show: 250
40-
},
36+
tippy(this, {
37+
appendTo: () => document.body,
38+
placement: 'top-start',
39+
delay: 250,
40+
content: el,
41+
allowHTML: true,
42+
interactive: true,
43+
arrow: `<svg width="16" height="6"><path d="m0 6 8-6 8 6Z" class="tippy-svg-arrow"/><path d="m0 7 8-6 8 6Z" class="tippy-svg-arrow-content"/></svg>`,
4144
onShow: () => {
42-
view.$emit('load-context-popup', {owner, repo, index}, () => {
43-
$(this).popup('reposition');
44-
});
45-
},
46-
popup: $(el),
45+
view.$emit('load-context-popup', {owner, repo, index});
46+
}
4747
});
4848
});
4949
}

Diff for: web_src/less/features/tippy.less

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
.tippy-box[data-animation="fade"][data-state="hidden"] {
2+
opacity: 0;
3+
}
4+
5+
[data-tippy-root] {
6+
max-width: calc(100vw - 10px);
7+
}
8+
9+
.tippy-box {
10+
position: relative;
11+
background-color: var(--color-body);
12+
color: var(--color-secondary-dark-6);
13+
border: 1px solid var(--color-secondary);
14+
border-radius: var(--border-radius);
15+
padding: .5em;
16+
font-size: 1rem;
17+
transition-property: transform, visibility, opacity;
18+
}
19+
20+
.tippy-box[data-inertia][data-state="visible"] {
21+
transition-timing-function: cubic-bezier(0.54, 1.5, 0.38, 1.11);
22+
}
23+
24+
.tippy-content {
25+
position: relative;
26+
padding: 5px 9px;
27+
z-index: 1;
28+
}
29+
30+
.tippy-svg-arrow {
31+
fill: var(--color-secondary);
32+
}
33+
34+
.tippy-svg-arrow-content {
35+
fill: var(--color-body);
36+
}
37+
38+
.tippy-box[data-placement^="top"] > .tippy-svg-arrow {
39+
bottom: 0;
40+
}
41+
42+
.tippy-box[data-placement^="top"] > .tippy-svg-arrow:after,
43+
.tippy-box[data-placement^="top"] > .tippy-svg-arrow > svg {
44+
top: 16px;
45+
transform: rotate(180deg);
46+
}
47+
48+
.tippy-box[data-placement^="bottom"] > .tippy-svg-arrow {
49+
top: 0;
50+
}
51+
52+
.tippy-box[data-placement^="bottom"] > .tippy-svg-arrow > svg {
53+
bottom: 16px;
54+
}
55+
56+
.tippy-box[data-placement^="left"] > .tippy-svg-arrow {
57+
right: 0;
58+
}
59+
60+
.tippy-box[data-placement^="left"] > .tippy-svg-arrow:after,
61+
.tippy-box[data-placement^="left"] > .tippy-svg-arrow > svg {
62+
transform: rotate(90deg);
63+
top: calc(50% - 3px);
64+
left: 11px;
65+
}
66+
67+
.tippy-box[data-placement^="right"] > .tippy-svg-arrow {
68+
left: 0;
69+
}
70+
71+
.tippy-box[data-placement^="right"] > .tippy-svg-arrow:after,
72+
.tippy-box[data-placement^="right"] > .tippy-svg-arrow > svg {
73+
transform: rotate(-90deg);
74+
top: calc(50% - 3px);
75+
right: 11px;
76+
}
77+
78+
.tippy-svg-arrow {
79+
width: 16px;
80+
height: 16px;
81+
text-align: initial;
82+
}
83+
84+
.tippy-svg-arrow,
85+
.tippy-svg-arrow > svg {
86+
position: absolute;
87+
}

Diff for: web_src/less/index.less

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
@import "./features/imagediff.less";
1010
@import "./features/codeeditor.less";
1111
@import "./features/projects.less";
12+
@import "./features/tippy.less";
1213
@import "./markup/content.less";
1314
@import "./markup/codecopy.less";
1415
@import "./code/linebutton.less";

0 commit comments

Comments
 (0)