float
Parks an element next to an anchor and keeps it there while the page scrolls or
resizes. The geometry — flip to the side that fits, then shift to stay on screen —
comes from compute_position in svelte-widgets/utils, which the tooltip and the
portalled dropdown also use. The anchor can be a plain rect instead of an element,
which is how ActionMenu hangs its context form off the pointer.
anchor
floating
svelte<script lang="ts">
import { float } from '$lib/attachments'
import type { Placement } from '$lib/utils'
let anchor = $state<HTMLElement | null>(null)
let placement = $state<Placement>(`bottom`)
</script>
<label for="float-placement">Placement</label>
<select id="float-placement" bind:value={placement}>
{#each [`top`, `right`, `bottom`, `left`] as side (side)}<option>{side}</option>{/each}
</select>
<div style="display: grid; place-items: center; height: 12em">
<span bind:this={anchor} style="padding: 1ex 1em; border: 1px dashed gray">anchor</span>
</div>
<div
style="background: teal; color: white; padding: 2pt 6pt; border-radius: 4pt"
{@attach float({ anchor, placement, offset: 8, padding: 8 })}
>
floating
</div>