budibase/packages/bbui/src/Tooltip/Context.svelte

80 lines
1.6 KiB
Svelte
Raw Normal View History

2024-04-01 13:31:16 +02:00
<script>
import Portal from "svelte-portal"
2024-04-03 10:08:31 +02:00
import { getContext } from "svelte"
import Context from "../context"
2024-04-01 13:31:16 +02:00
export let anchor
export let visible = false
2024-04-22 09:50:33 +02:00
export let offset = 0
2024-04-03 00:07:48 +02:00
2024-04-04 09:38:25 +02:00
$: target = getContext(Context.PopoverRoot) || "#app"
2024-04-03 10:08:31 +02:00
2024-04-03 00:07:48 +02:00
let hovering = false
let tooltip
let x = 0
let y = 0
2024-04-01 13:31:16 +02:00
const updatePosition = (anchor, tooltip) => {
if (anchor == null || tooltip == null) {
2024-04-22 09:50:33 +02:00
return
2024-04-02 17:46:31 +02:00
}
2024-04-01 13:31:16 +02:00
2024-04-02 11:54:20 +02:00
requestAnimationFrame(() => {
2024-04-22 09:50:33 +02:00
const rect = anchor.getBoundingClientRect()
const windowOffset =
window.innerHeight - offset - (tooltip.clientHeight + rect.y)
const tooltipWidth = tooltip.clientWidth
2024-04-04 08:53:30 +02:00
x = rect.x - tooltipWidth - offset
y = windowOffset < 0 ? rect.y + windowOffset : rect.y
2024-04-02 17:46:31 +02:00
})
2024-04-01 18:14:18 +02:00
}
2024-04-01 13:31:16 +02:00
$: updatePosition(anchor, tooltip)
2024-04-01 13:31:16 +02:00
2024-04-22 09:46:00 +02:00
const handleMouseenter = () => {
2024-04-22 09:50:33 +02:00
hovering = true
2024-04-01 13:31:16 +02:00
}
2024-04-22 09:46:00 +02:00
const handleMouseleave = () => {
2024-04-22 09:50:33 +02:00
hovering = false
2024-04-01 13:31:16 +02:00
}
</script>
2024-04-03 10:08:31 +02:00
<Portal {target}>
2024-04-01 13:31:16 +02:00
<div
2024-04-22 09:46:00 +02:00
role="tooltip"
2024-04-01 13:31:16 +02:00
on:mouseenter={handleMouseenter}
on:mouseleave={handleMouseleave}
style:left={`${x}px`}
style:top={`${y}px`}
class="wrapper"
2024-04-01 13:31:16 +02:00
class:visible={visible || hovering}
>
2024-04-22 09:50:33 +02:00
<div bind:this={tooltip} class="tooltip">
<slot />
2024-04-02 11:54:20 +02:00
</div>
2024-04-01 13:31:16 +02:00
</div>
</Portal>
<style>
.wrapper {
2024-05-15 00:05:04 +02:00
background-color: var(--spectrum-global-color-gray-100);
2024-04-22 09:50:33 +02:00
box-shadow: 2px 2px 5px 0px rgba(0, 0, 0, 0.42);
opacity: 0;
overflow: hidden;
2024-04-05 08:33:14 +02:00
2024-04-03 00:07:48 +02:00
border-radius: 5px;
box-sizing: border-box;
2024-04-04 15:53:36 +02:00
border: 1px solid var(--grey-4);
2024-04-02 17:46:31 +02:00
position: absolute;
2024-04-22 09:17:23 +02:00
pointer-events: none;
z-index: 1000;
2024-04-05 10:48:38 +02:00
}
2024-04-01 13:31:16 +02:00
.visible {
opacity: 1;
pointer-events: auto;
}
</style>