Skip to content

Floating Context

The context is the shared root that keeps a floating surface together.

If you understand the floating context, the rest of the library gets easier to follow. Most confusion in VFloat comes from treating the composables as separate helpers when they are really meant to cooperate through one shared object.

The Three Parts

Every floating surface in VFloat is built from three things:

  • an anchor element
  • a floating element
  • a shared context

The anchor is the thing the surface is positioned against. The floating element is the surface that appears. The context is the object that connects them and lets other composables work together.

Why The Context Exists

VFloat intentionally keeps the shared context small:

  • refs
  • state

That grouping matters because companion composables know where to read and write behavior without forcing the public root shape to grow in random directions. Positioning is added separately with usePosition, which reads the same context and returns the computed geometry.

refs

The refs group is about the DOM relationships.

It includes:

  • anchorEl
  • floatingEl
  • arrowEl

state

The state group is about visibility.

It includes:

  • open
  • setOpen

Interaction composables such as useHover, useClick, useFocus, and useEscapeKey all coordinate through this same state object.

Positioning Lives Next To The Context

The context itself does not compute coordinates, run middlewares, or wire auto-update listeners.

When a surface needs JavaScript positioning, call usePosition(context). That returns geometry fields such as:

  • x
  • y
  • placement
  • strategy
  • middlewareData
  • isPositioned
  • styles
  • update

Most templates only need styles.value, but the rest of the data is there when you need deeper control or helpers such as arrows.

The Core Loop

This is the loop to keep in your head:

  1. You create refs for the anchor and floating element.
  2. You pass them into useFloatingContext.
  3. useFloatingContext() returns the shared context.
  4. usePosition(context) adds positioning when the surface needs it.
  5. Other composables read from and write to the same context.
  6. Your template renders from context.state and the returned styles.

A Minimal Example

This small example shows the context in use without much extra ceremony.

vue
<script setup lang="ts">
import { ref } from "vue";
import { useFloatingContext, usePosition, useHover } from "v-float";

const anchorEl = ref<HTMLElement | null>(null);
const floatingEl = ref<HTMLElement | null>(null);

const context = useFloatingContext({ refs: { anchorEl, floatingEl } });
const { styles } = usePosition(context, {
  placement: "bottom",
  middleware: {
    offset: 8,
  },
});

useHover(context);
</script>

<template>
  <button ref="anchorEl" type="button">Hover me</button>

  <div v-if="context.state.open.value" ref="floatingEl" :style="styles">Floating content</div>
</template>

Next Step

Floating Context has loaded