Skip to content

Commit

Permalink
feat(UI): Add a tooltip component (#528)
Browse files Browse the repository at this point in the history
In prevision of #394 this PR adds a tooltip component.

Usage: 

```vue
<script setup>
import FloatingTooltip from "@/components/FloatingTooltip.vue";
</script>

<template>
  <FloatingTooltip text="Tooltip on div">bottom tooltip</FloatingTooltip>
  <FloatingTooltip text="Tooltip on div" placement="top">top tooltip</FloatingTooltip>
  <FloatingTooltip text="Tooltip on div" placement="left">left tooltip</FloatingTooltip>
  <FloatingTooltip text="Tooltip on div" placement="right">right tooltip</FloatingTooltip>
  <FloatingTooltip placement="right">
    html tooltip
    <template #tooltipContent>
      <span style="color: red">red content</span>
    </template>
  </FloatingTooltip>
</template>
```

UI preview:


https://github.com/user-attachments/assets/0b2a0d7c-654d-465f-a995-6266f45d60d5
  • Loading branch information
rouk1 authored Oct 18, 2024
1 parent 11aecba commit 0175c71
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 7 deletions.
2 changes: 1 addition & 1 deletion skore-ui/src/assets/styles/_variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
--toast-border-color: rgb(255 255 255);
--toast-text-color: rgb(0 0 0);
--toast-dismiss-color: hsl(0deg 0% 35%);
--toast-shadow-elevation: rgb(255 255 255 / 48%);
--toast-shadow-elevation: rgb(0 0 0 / 48%);
--toast-shadow-inset: inset 0 0 1.1px 2px rgb(0 0 0 / 13%);
}
}
Expand Down
59 changes: 59 additions & 0 deletions skore-ui/src/components/FloatingTooltip.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<script setup lang="ts">
import { autoUpdate, offset, useFloating, type Placement } from "@floating-ui/vue";
import { ref } from "vue";
const props = defineProps<{ text?: string; placement?: Placement }>();
const isHover = ref(false);
const reference = ref<HTMLElement>();
const floating = ref<HTMLDivElement>();
const { floatingStyles } = useFloating(reference, floating, {
middleware: [offset(10)],
placement: props.placement ?? "bottom",
whileElementsMounted: autoUpdate,
});
</script>

<template>
<span
class="floating-tooltip"
ref="reference"
@mouseenter="isHover = true"
@mouseleave="isHover = false"
>
<slot></slot>
<Transition name="fade">
<span
v-if="isHover"
ref="floating"
class="floating-tooltip-content"
:class="props.placement"
:style="floatingStyles"
>
<template v-if="$slots.tooltipContent">
<slot name="tooltipContent"></slot>
</template>
<template v-else>
{{ props.text }}
</template>
</span>
</Transition>
</span>
</template>

<style scoped>
.floating-tooltip {
position: relative;
.floating-tooltip-content {
position: absolute;
z-index: 9999;
width: max-content;
padding: var(--spacing-padding-small);
border: solid var(--border-width-small) var(--border-color-normal);
border-radius: var(--border-radius);
background-color: var(--background-color-normal);
box-shadow: 0 4px 18.2px -2px var(--toast-shadow-elevation);
}
}
</style>
8 changes: 4 additions & 4 deletions skore-ui/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import "./assets/styles/main.css";

import { createPinia } from "pinia";
import { createApp } from "vue";

import App from "./App.vue";
import router from "./router";
import "@/assets/styles/main.css";

import App from "@/App.vue";
import router from "@/router";

const app = createApp(App);

Expand Down
35 changes: 33 additions & 2 deletions skore-ui/src/views/ComponentsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import DropdownButton from "@/components/DropdownButton.vue";
import DropdownButtonItem from "@/components/DropdownButtonItem.vue";
import DynamicContentRasterizer from "@/components/DynamicContentRasterizer.vue";
import EditableList, { type EditableListItemModel } from "@/components/EditableList.vue";
import FloatingTooltip from "@/components/FloatingTooltip.vue";
import HtmlSnippetWidget from "@/components/HtmlSnippetWidget.vue";
import ImageWidget from "@/components/ImageWidget.vue";
import MarkdownWidget from "@/components/MarkdownWidget.vue";
Expand Down Expand Up @@ -178,6 +179,7 @@ const isCached = ref(false);
'icons',
'draggable list',
'cacheable component',
'tooltip',
]"
>
<TabsItem :value="0">
Expand Down Expand Up @@ -431,7 +433,7 @@ const isCached = ref(false);
<div>icon-handle <span class="icon-handle"></span></div>
</div>
</TabsItem>
<TabsItem :value="13">
<TabsItem :value="12">
<Simplebar class="draggable-list-container">
<DraggableList
v-model:items="draggableListData"
Expand All @@ -448,7 +450,7 @@ const isCached = ref(false);
</DraggableList>
</Simplebar>
</TabsItem>
<TabsItem :value="14">
<TabsItem :value="13">
<label>
Cache the following widget
<input type="checkbox" v-model="isCached" />
Expand All @@ -458,6 +460,28 @@ const isCached = ref(false);
<HtmlSnippetWidget :src="htmlSnippet" />
</DynamicContentRasterizer>
</TabsItem>
<TabsItem :value="14" class="floating-tooltip-tab">
<div>
<FloatingTooltip text="Tooltip on div">bottom tooltip</FloatingTooltip>
</div>
<div>
<FloatingTooltip text="Tooltip on div" placement="top">top tooltip</FloatingTooltip>
</div>
<div>
<FloatingTooltip text="Tooltip on div" placement="left">left tooltip</FloatingTooltip>
</div>
<div>
<FloatingTooltip text="Tooltip on div" placement="right">right tooltip</FloatingTooltip>
</div>
<div>
<FloatingTooltip placement="right">
html tooltip
<template #tooltipContent>
<span style="color: red">red content</span>
</template>
</FloatingTooltip>
</div>
</TabsItem>
</Tabs>
</main>
</template>
Expand Down Expand Up @@ -537,4 +561,11 @@ main {
max-height: 80vh;
margin-top: 10px;
}
.floating-tooltip-tab {
display: grid;
padding: 40px;
gap: 40px;
grid-template-columns: 1fr 1fr 1fr;
}
</style>

0 comments on commit 0175c71

Please sign in to comment.