Files
windmill/frontend/src/lib/components/CustomPopover.svelte
T
Ruben Fiszel dbcf5c3590 chore(internal): upgrade vite (#7461)
* vite 8

* add .npmrc

* popperjs to svelte 5

* popperjs to svelte 5

* revert to rolldown-vite

* vite 7.3.0
2025-12-27 10:23:21 +00:00

105 lines
2.4 KiB
Svelte

<script lang="ts">
import { run, createBubbler } from 'svelte/legacy'
const bubble = createBubbler()
import { createPopperActions, type PopperOptions } from 'svelte-popperjs'
import type { PopoverPlacement } from './Popover.model'
import Portal from '$lib/components/Portal.svelte'
interface Props {
placement?: PopoverPlacement
notClickable?: boolean
disablePopup?: boolean
disappearTimeout?: number
appearTimeout?: number
style?: string | undefined
noPadding?: boolean
focusEl?: HTMLElement | undefined
class?: string
children?: import('svelte').Snippet
overlay?: import('svelte').Snippet
}
let {
placement = 'bottom-end',
notClickable = false,
disablePopup = false,
disappearTimeout = 100,
appearTimeout = 300,
style = undefined,
noPadding = false,
focusEl = undefined,
class: clazz = '',
children,
overlay
}: Props = $props()
const [popperRef, popperContent] = createPopperActions({ placement })
const popperOptions: PopperOptions<{}> = {
placement,
strategy: 'fixed',
modifiers: [
{ name: 'offset', options: { offset: [8, 8] } },
{
name: 'arrow',
options: {
padding: 10
}
}
]
}
let showTooltip = $state(false)
let timeout: number | undefined = undefined
let inTimeout: number | undefined = undefined
function open() {
clearTimeout(timeout)
if (appearTimeout == 0) {
showTooltip = true
} else {
inTimeout = setTimeout(() => (showTooltip = true), appearTimeout)
}
}
function close() {
inTimeout && clearTimeout(inTimeout)
inTimeout = undefined
timeout = setTimeout(() => (showTooltip = false), disappearTimeout)
}
run(() => {
focusEl && focusEl?.focus()
})
</script>
{#if notClickable}
<!-- svelte-ignore a11y_no_static_element_interactions -->
<span {style} use:popperRef onmouseenter={open} onmouseleave={close} class={clazz}>
{@render children?.()}
</span>
{:else}
<button
{style}
use:popperRef
onmouseenter={open}
onmouseleave={close}
onclick={bubble('click')}
class={clazz}
>
{@render children?.()}
</button>
{/if}
{#if showTooltip && !disablePopup}
<Portal name="custom-popover">
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
use:popperContent={popperOptions}
onmouseenter={open}
onmouseleave={close}
class="z-[5001] border rounded-lg shadow-lg {noPadding ? '' : 'p-4'} bg-surface"
>
{@render overlay?.()}
</div>
</Portal>
{/if}