Skip to content
llms.txt
llms.txt

Client point

Open the live client-point demo

Live demo

Client point

Source for this preview

ClientPointExample.astro
<article id="client-point-demo" class="demo-card client-point-card">
<div class="card-top">
<span class="number">D</span><span class="chip">virtual reference</span>
</div>
<h3>Cursor signal</h3>
<p>
Move across the field. A virtual reference follows the pointer instead of
the whole element.
</p>
<div class="card-action">
<floating-root id="client-point-root" placement="top">
<floating-reference>
<div class="cursor-field" tabindex="0">
<span id="pointer-label">Awaiting pointer</span>
<i aria-hidden="true"></i><i aria-hidden="true"></i>
<i aria-hidden="true"></i>
</div>
</floating-reference>
<template slot="content">
<div class="cursor-tooltip">Pointer is the <b>reference</b></div>
</template>
</floating-root>
</div>
<code>&lt;floating-root&gt; + clientPoint()</code>
</article>
<script>
import {
FloatingRootElement,
clientPoint,
dismiss,
flip,
hover,
offset,
role,
shift,
transformOrigin,
} from '@floating-ui-plus/web-components';
import {initializeExample} from './initialize-example';
initializeExample('client-point', (scope) => {
const floating = FloatingRootElement.query(
scope,
'#client-point-root',
);
const field = scope.querySelector<HTMLElement>('.cursor-field');
const label = scope.querySelector<HTMLElement>('#pointer-label');
if (!field || !label) return;
floating.configure({
middleware: [
offset(16),
flip(),
shift({padding: 18}),
transformOrigin({padding: 8}),
],
plugins: [
hover({move: true}),
clientPoint(),
dismiss(),
role({role: 'tooltip'}),
],
});
let frame: number | null = null;
let nextLabel = label.textContent ?? '';
field.addEventListener('mousemove', (event) => {
const bounds = field.getBoundingClientRect();
nextLabel = `${Math.round(event.clientX - bounds.left)} × ${Math.round(event.clientY - bounds.top)}`;
if (frame != null) return;
frame = requestAnimationFrame(() => {
frame = null;
label.textContent = nextLabel;
});
});
});
</script>

Open the full demo ↗

clientPoint() turns the pointer into a virtual reference. Combine it with hover({move: true}) to follow the cursor:

floating.configure({
middleware: [offset(16), flip(), shift({padding: 18})],
plugins: [
hover({move: true}),
clientPoint(),
dismiss(),
role({role: 'tooltip'}),
],
});

The demo’s coordinate readout is application code updated with requestAnimationFrame; Floating UI Plus only owns the virtual reference, position, and interaction lifecycle. Use this pattern for cursor annotations, context hints, and canvas overlays. The Vue adapter accepts the same clientPoint() plugin through useFloating() or FloatingRoot.