hono-preact
Overview
Quick Start
The Route Table
Layouts & Nesting
Adding Pages
Active Links
Server Loaders
Loading States
Reloading Data
Prefetching
Streaming
Live Loaders
Realtime Channels
Server Actions
Validation
Optimistic UI
View Transitions
Middleware
CSRF Protection
CLI
Vite Config
Project Structure
Composing Hono Middleware
WebSockets
Rooms & Presence
renderPage
Link Prefetch
Build & Deploy
Overview
Dialog
Popover
Tooltip
Menu
Context Menu
Select
Combobox
Toast
renderElement
useControllableState
mergeRefs
useListNavigation
useTypeahead
useListboxSelection
usePosition
usePositioner
useDismiss
useFocusReturn
useSafeArea
usePresence

usePosition#

Hook to keep a floating element anchored to a reference element, with preferred side and alignment, automatic repositioning on scroll and resize, and optional arrow offset data. It wraps Floating UI and is the positioning layer Popover and Tooltip use internally; reach for it when building your own custom floating components.

Demo#

side
align

Signature#

import { usePosition } from 'hono-preact-ui';

function usePosition(opts: UsePositionOptions): PositionState;

interface UsePositionOptions {
  open: boolean;
  anchorRef: RefObject<HTMLElement>;
  floatingRef: RefObject<HTMLElement>;
  arrowRef?: RefObject<HTMLElement>;
  getAnchorRect?: ClientRectGetter; // position against a point/virtual element
  side?: 'top' | 'right' | 'bottom' | 'left'; // default 'bottom'
  align?: 'start' | 'center' | 'end'; // default 'center'
  offset?: number; // gap in px, default 8
}

interface PositionState {
  side: 'top' | 'right' | 'bottom' | 'left';
  align: 'start' | 'center' | 'end';
  arrowX: number | null;
  arrowY: number | null;
}

Options#

OptionTypeDefaultNotes
openbooleannonePositioning runs only while open.
anchorRefRefObjectnoneThe reference element.
floatingRefRefObjectnoneThe element being positioned.
arrowRefRefObjectoptionalEnables arrow positioning.
getAnchorRectClientRectGetteroptionalPosition against a point or virtual element instead of anchorRef (e.g. a pointer position).
side'top' | 'right' | 'bottom' | 'left''bottom'Preferred side.
align'start' | 'center' | 'end''center'Alignment along the side.
offsetnumber8Gap in pixels.

Returns#

FieldTypeDescription
side'top' | 'right' | 'bottom' | 'left'Resolved side after collision handling.
align'start' | 'center' | 'end'Resolved alignment.
arrowXnumber | nullArrow x offset in px, or null.
arrowYnumber | nullArrow y offset in px, or null.

Helpers#

Two pure helpers convert between the hook's (side, align) model and a Floating UI Placement string. Both are exported from hono-preact-ui for building your own positioning logic on top of the same mapping the components use.

import { placementFor, sideAlignFromPlacement } from 'hono-preact-ui';

// (side, align) -> Placement: 'center' is the bare side; 'start'/'end' add the suffix.
function placementFor(
  side: 'top' | 'right' | 'bottom' | 'left',
  align: 'start' | 'center' | 'end'
): Placement; // e.g. ('bottom', 'start') -> 'bottom-start'

// Placement -> (side, align): the inverse, for rendering data-side / data-align.
function sideAlignFromPlacement(placement: Placement): {
  side: 'top' | 'right' | 'bottom' | 'left';
  align: 'start' | 'center' | 'end';
};

Placement is the Floating UI placement union (e.g. 'bottom', 'bottom-start', 'left-end').