Skip to content
On this page

useArrow

useArrow owns arrow registration for a floating context and returns the computed arrow coordinates and styles.

Type

ts
function useArrow(context: UseArrowContext, options?: UseArrowOptions): UseArrowReturn;

interface UseArrowContext {
  id: FloatingContextId;
  refs: FloatingContext["refs"];
}

interface UseArrowOptions {
  offset?: string;
  padding?: Padding;
}

interface UseArrowReturn {
  arrowX: ComputedRef<number>;
  arrowY: ComputedRef<number>;
  arrowStyles: ComputedRef<Record<string, string>>;
}

Details

useArrow connects an arrow element to the floating context and registers the arrow middleware for that context.

  • context.refs.arrowEl is the arrow element used by the middleware.
  • offset defaults to "-4px".
  • padding is passed to the arrow middleware.
  • middlewareData and placement are read from the floating context internals registered by usePosition().
  • The arrow element still needs its own absolute positioning, since arrowStyles only supplies inset offsets.

Example

This example shows the root-first useArrow() form.

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

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

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

useHover(context);

const { arrowStyles } = useArrow(context, {
  offset: "-4px",
});
</script>

<template>
  <button ref="anchorEl">Anchor</button>

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

See Also

useArrow has loaded