Skip to content

Commit 50808bf

Browse files
committed
Replaced Vue-Tippy with our own Popover-based tooltip component.
PrimeVue has its own tooltip component, but it doesn't support HTML and Vue-Tippy doesn't look like the rest of PrimeVue, and we want both, so...
1 parent 20a8f46 commit 50808bf

7 files changed

Lines changed: 115 additions & 150 deletions

File tree

src/renderer/src/assets/app.css

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,6 @@ body {
4646
transition: none !important;
4747
}
4848

49-
.tippy-box[data-theme~='opencor'] ul {
50-
list-style: disc;
51-
}
52-
53-
.tippy-box[data-theme~='opencor'] {
54-
background-color: var(--p-content-background);
55-
color: var(--p-content-color);
56-
box-shadow: 0 2px 8px var(--p-shadow-color, rgba(0, 0, 0, 0.15));
57-
border-radius: var(--p-content-border-radius);
58-
}
59-
60-
.tippy-box[data-theme~='opencor'] > .tippy-arrow {
61-
color: var(--p-content-background);
62-
}
63-
6449
a {
6550
color: var(--p-button-link-color);
6651
}
@@ -70,7 +55,3 @@ body {
7055
}
7156
}
7257
}
73-
74-
html.opencor-dark-mode .opencor .tippy-box[data-theme~='opencor'] {
75-
box-shadow: 0 2px 8px var(--p-shadow-color-dark, rgba(255, 255, 255, 0.15));
76-
}

src/renderer/src/common/dependencies.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ export let _jsonSchema: Module = null;
77
export let _jsZip: Module = null;
88
export let _mathJs: Module = null;
99
export let _plotlyJs: Module = null;
10-
export let _vueTippy: Module = null;
1110
export let _xxhash: Module = null;
1211

1312
export const setJsonSchema = (module: Module): void => {
@@ -26,10 +25,6 @@ export const setPlotlyJs = (module: Module): void => {
2625
_plotlyJs = module;
2726
};
2827

29-
export const setVueTippy = (module: Module): void => {
30-
_vueTippy = module;
31-
};
32-
3328
export const initialiseXxhash: Promise<Module> = xxhash().then((module: Module) => {
3429
_xxhash = module;
3530

src/renderer/src/common/initialisation.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,6 @@ const externalDependencies: ExternalDependency[] = [
3535
name: 'Plotly.js',
3636
url: 'https://cdn.jsdelivr.net/npm/plotly.js-gl2d-dist-min@3.6.0/+esm',
3737
set: (m) => dependencies.setPlotlyJs(m)
38-
},
39-
{
40-
name: 'VueTippy',
41-
url: 'https://cdn.jsdelivr.net/npm/vue-tippy@6.7.1/+esm',
42-
set: (m) => dependencies.setVueTippy(m),
43-
cssUrl: 'https://cdn.jsdelivr.net/npm/tippy.js@6.3.7/dist/tippy.css'
4438
}
4539
];
4640

src/renderer/src/components/OpenCOR.vue

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ import '../assets/app.css';
134134
import '../assets/primeicons-assets';
135135
import * as common from '../common/common';
136136
import { FULL_URI_SCHEME, LONG_DELAY, SHORT_DELAY, TOAST_LIFE } from '../common/constants';
137-
import * as dependencies from '../common/dependencies';
138137
import { electronApi } from '../common/electronApi';
139138
/* TODO: enable once our GitHub integration is fully ready.
140139
import firebaseConfig, { missingFirebaseKeys } from '../common/firebaseConfig';
@@ -445,8 +444,6 @@ provideOpenCORToast(addToast);
445444
446445
// Finish initialising OpenCOR.
447446
448-
const crtGlobalProperties = crtVueAppInstance?.config.globalProperties as Record<string, unknown> | undefined;
449-
const vueTippyInstalledFlag = 'opencorVueTippyInstalled';
450447
let postInitialisationDone = false;
451448
452449
vue.watch(
@@ -455,25 +452,6 @@ vue.watch(
455452
if (newInitialisationDone && !postInitialisationDone) {
456453
postInitialisationDone = true;
457454
458-
// OpenCOR is now fully initialised, so we can finalise a few things, namely let the current Vue app instance use
459-
// VueTippy.
460-
461-
if (crtVueAppInstance && crtGlobalProperties && !crtGlobalProperties[vueTippyInstalledFlag]) {
462-
// Append Tippy tooltips to `.opencor` rather than `document.body` so that they stay within the component's
463-
// stacking context. This is critical when OpenCOR is embedded as a Vue 3 component in a host app in full-screen
464-
// mode (`document.body` can be hidden behind the host's full-screen container, whereas `.opencor` lives inside
465-
// it).
466-
467-
crtVueAppInstance.use(dependencies._vueTippy, {
468-
defaultProps: {
469-
appendTo: () => document.querySelector('.opencor') || document.body,
470-
theme: 'opencor'
471-
}
472-
});
473-
474-
crtGlobalProperties[vueTippyInstalledFlag] = true;
475-
}
476-
477455
// Now, we can hide the loading message (but after a long delay so that the user gets a chance to see that the
478456
// initialisation has reached 100%).
479457

src/renderer/src/components/dialogs/SimulationExperimentViewSettingsDialog.vue

Lines changed: 54 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -348,16 +348,12 @@
348348
/>
349349
<label>Model parameter</label>
350350
</FloatLabel>
351-
<FloatLabel variant="on" class="flex-1">
352-
<InputText v-model="parameter.value" class="w-full" size="small"
353-
v-tippy="{
354-
allowHTML: true,
355-
content: parameterValueTooltip(),
356-
placement: 'bottom-start'
357-
}"
358-
/>
359-
<label>Value</label>
360-
</FloatLabel>
351+
<Tooltip :content="parameterValueTooltip()" class="flex-1">
352+
<FloatLabel variant="on" class="w-full">
353+
<InputText v-model="parameter.value" class="w-full" size="small" />
354+
<label>Value</label>
355+
</FloatLabel>
356+
</Tooltip>
361357
<Button
362358
icon="pi pi-times"
363359
text rounded
@@ -524,26 +520,18 @@
524520
<!-- Description and VOI expression -->
525521

526522
<div class="form-row">
527-
<FloatLabel variant="on" class="flex-1">
528-
<InputText v-model="externalDataFile.description" class="w-full" size="small"
529-
v-tippy="{
530-
allowHTML: true,
531-
content: externalDataDescriptionTooltip(),
532-
placement: 'bottom-start'
533-
}"
534-
/>
535-
<label>Description (optional)</label>
536-
</FloatLabel>
537-
<FloatLabel variant="on" class="flex-1">
538-
<InputText v-model="externalDataFile.voiExpression" class="w-full" size="small"
539-
v-tippy="{
540-
allowHTML: true,
541-
content: externalDataVoiExpressionTooltip(),
542-
placement: 'bottom-start'
543-
}"
544-
/>
545-
<label>VOI expression (optional)</label>
546-
</FloatLabel>
523+
<Tooltip :content="externalDataDescriptionTooltip()" class="flex-1">
524+
<FloatLabel variant="on" class="w-full">
525+
<InputText v-model="externalDataFile.description" class="w-full" size="small" />
526+
<label>Description (optional)</label>
527+
</FloatLabel>
528+
</Tooltip>
529+
<Tooltip :content="externalDataVoiExpressionTooltip()" class="flex-1">
530+
<FloatLabel variant="on" class="w-full">
531+
<InputText v-model="externalDataFile.voiExpression" class="w-full" size="small" />
532+
<label>VOI expression (optional)</label>
533+
</FloatLabel>
534+
</Tooltip>
547535
</div>
548536

549537
<!-- External data entries -->
@@ -675,38 +663,26 @@
675663
</div>
676664
<div class="w-full">
677665
<div class="mb-3">
678-
<FloatLabel variant="on" class="flex-1">
679-
<InputText v-model="plot.name" class="w-full" size="small"
680-
v-tippy="{
681-
allowHTML: true,
682-
content: traceNameTooltip(),
683-
placement: 'bottom-start'
684-
}"
685-
/>
686-
<label>Name (optional)</label>
687-
</FloatLabel>
666+
<Tooltip :content="traceNameTooltip()" class="flex-1">
667+
<FloatLabel variant="on" class="w-full">
668+
<InputText v-model="plot.name" class="w-full" size="small" />
669+
<label>Name (optional)</label>
670+
</FloatLabel>
671+
</Tooltip>
688672
</div>
689673
<div class="entry-row">
690-
<FloatLabel variant="on" class="flex-1">
691-
<InputText v-model="plot.xValue" class="w-full" size="small"
692-
v-tippy="{
693-
allowHTML: true,
694-
content: xyValueTooltip(true),
695-
placement: 'bottom-start'
696-
}"
697-
/>
698-
<label>X value</label>
699-
</FloatLabel>
700-
<FloatLabel variant="on" class="flex-1">
701-
<InputText v-model="plot.yValue" class="w-full" size="small"
702-
v-tippy="{
703-
allowHTML: true,
704-
content: xyValueTooltip(false),
705-
placement: 'bottom-start'
706-
}"
707-
/>
708-
<label>Y value</label>
709-
</FloatLabel>
674+
<Tooltip :content="xyValueTooltip(true)" class="flex-1">
675+
<FloatLabel variant="on" class="w-full">
676+
<InputText v-model="plot.xValue" class="w-full" size="small" />
677+
<label>X value</label>
678+
</FloatLabel>
679+
</Tooltip>
680+
<Tooltip :content="xyValueTooltip(false)" class="flex-1">
681+
<FloatLabel variant="on" class="w-full">
682+
<InputText v-model="plot.yValue" class="w-full" size="small" />
683+
<label>Y value</label>
684+
</FloatLabel>
685+
</Tooltip>
710686
</div>
711687
</div>
712688
<Button
@@ -732,38 +708,26 @@
732708
</div>
733709
<div class="w-full">
734710
<div class="mb-3">
735-
<FloatLabel variant="on" class="flex-1">
736-
<InputText v-model="trace.name" class="w-full" size="small"
737-
v-tippy="{
738-
allowHTML: true,
739-
content: traceNameTooltip(),
740-
placement: 'bottom-start'
741-
}"
742-
/>
743-
<label>Name (optional)</label>
744-
</FloatLabel>
711+
<Tooltip :content="traceNameTooltip()" class="flex-1">
712+
<FloatLabel variant="on" class="w-full">
713+
<InputText v-model="trace.name" class="w-full" size="small" />
714+
<label>Name (optional)</label>
715+
</FloatLabel>
716+
</Tooltip>
745717
</div>
746718
<div class="entry-row">
747-
<FloatLabel variant="on" class="flex-1">
748-
<InputText v-model="trace.xValue" class="w-full" size="small"
749-
v-tippy="{
750-
allowHTML: true,
751-
content: xyValueTooltip(true),
752-
placement: 'bottom-start'
753-
}"
754-
/>
755-
<label>X value</label>
756-
</FloatLabel>
757-
<FloatLabel variant="on" class="flex-1">
758-
<InputText v-model="trace.yValue" class="w-full" size="small"
759-
v-tippy="{
760-
allowHTML: true,
761-
content: xyValueTooltip(false),
762-
placement: 'bottom-start'
763-
}"
764-
/>
765-
<label>Y value</label>
766-
</FloatLabel>
719+
<Tooltip :content="xyValueTooltip(true)" class="flex-1">
720+
<FloatLabel variant="on" class="w-full">
721+
<InputText v-model="trace.xValue" class="w-full" size="small" />
722+
<label>X value</label>
723+
</FloatLabel>
724+
</Tooltip>
725+
<Tooltip :content="xyValueTooltip(false)" class="flex-1">
726+
<FloatLabel variant="on" class="w-full">
727+
<InputText v-model="trace.yValue" class="w-full" size="small" />
728+
<label>Y value</label>
729+
</FloatLabel>
730+
</Tooltip>
767731
</div>
768732
</div>
769733
<Button

src/renderer/src/components/views/SimulationExperimentView.vue

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,16 +154,12 @@
154154
>
155155
<div class="flex items-center">
156156
<div class="w-1 h-6 rounded-xs mr-2" :style="`background-color: ${run.color};`"></div>
157-
<div class="grow text-sm"
157+
<Tooltip :content="run.isLiveRun ? '' : run.tooltip"
158+
class="grow text-sm"
158159
:class="{ 'cursor-help': !run.isLiveRun, 'opacity-50': !run.isVisible }"
159-
v-tippy="!run.isLiveRun ? {
160-
allowHTML: true,
161-
content: run.tooltip,
162-
placement: 'bottom-start'
163-
} : undefined"
164160
>
165161
{{ run.isLiveRun ? 'Live run' : `Run #${index}` }}
166-
</div>
162+
</Tooltip>
167163
<div class="flex items-center">
168164
<Button class="p-0! w-5! h-5! run-action-button"
169165
icon="pi pi-palette"
@@ -1748,7 +1744,7 @@ const onTrackRun = (): void => {
17481744
17491745
tooltipRows.push(`<tr>
17501746
<td>
1751-
<b>${input.name}:</b>
1747+
<strong>${input.name}:</strong>
17521748
</td>
17531749
<td style="padding-left: 8px;">
17541750
${inputValue}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<template>
2+
<div ref="wrapperRef" @mouseenter="onMouseEnter" @mouseleave="onMouseLeave">
3+
<slot />
4+
<Popover ref="popoverRef" class="tooltip" :appendTo="appendTarget" :closeOnEscape="false">
5+
<div class="tooltip" v-html="content" />
6+
</Popover>
7+
</div>
8+
</template>
9+
10+
<script setup lang="ts">
11+
import Popover from 'primevue/popover';
12+
import * as vue from 'vue';
13+
14+
import * as vueCommon from '../../common/vueCommon';
15+
16+
const props = defineProps<{
17+
content: string;
18+
}>();
19+
20+
const wrapperRef = vue.ref<HTMLElement | undefined>();
21+
const popoverRef = vue.ref<InstanceType<typeof Popover> | undefined>();
22+
const appendTarget = vueCommon.useAppendTarget();
23+
24+
const onMouseEnter = (event: MouseEvent) => {
25+
if (!props.content) {
26+
return;
27+
}
28+
29+
popoverRef.value?.show(event, wrapperRef.value);
30+
};
31+
32+
const onMouseLeave = () => {
33+
popoverRef.value?.hide();
34+
};
35+
</script>
36+
37+
<style scoped>
38+
.tooltip {
39+
max-width: 20rem;
40+
font-size: 0.8rem;
41+
}
42+
43+
.tooltip :deep(code) {
44+
font-size: 0.85em;
45+
padding: 0.1em 0.25em;
46+
background-color: var(--p-form-field-background);
47+
color: var(--p-form-field-color);
48+
border: 1px solid var(--p-form-field-border-color);
49+
border-radius: 0.2em;
50+
}
51+
</style>
52+
53+
<style>
54+
.tooltip .p-popover-content {
55+
padding: 0.375rem 0.625rem;
56+
}
57+
</style>

0 commit comments

Comments
 (0)