@fictjs/floating-ui-dom
v0.3.4
Published
Floating UI bindings for Fict DOM.
Maintainers
Readme
@fictjs/floating-ui-dom
Floating UI bindings for Fict DOM.
This package mirrors the core surface of @floating-ui/react-dom for Fict applications:
useFloating()creates positioning state, refs, and styles- middleware helpers like
offset(),flip(),shift(), andarrow()are re-exported - the runtime dependency remains
@floating-ui/dom
Why a Fict version
Fict components execute once and update through fine-grained signals rather than React rerenders. That changes two important usage patterns:
- dynamic
useFloating()options should be wrapped in accessors - returned positioning state is exposed as accessors, while
floatingStylesstays a live style object
The rest of the mental model stays the same: set a reference element, set a floating element, then apply floatingStyles.
Installation
pnpm add @fictjs/floating-ui-dom@fictjs/runtime is a peer dependency and is typically already present in a Fict app.
Basic usage
import { createSignal } from '@fictjs/runtime/advanced'
import { autoUpdate, flip, offset, shift, useFloating } from '@fictjs/floating-ui-dom'
function Popover() {
const open = createSignal(false)
const floating = useFloating<HTMLButtonElement>({
open,
whileElementsMounted: autoUpdate,
middleware: () => [offset(8), flip(), shift()],
})
return (
<>
<button ref={floating.refs.setReference} onClick={() => open(!open())}>
Toggle
</button>
{() =>
open() ? (
<div ref={floating.refs.setFloating} style={floating.floatingStyles}>
Floating content
</div>
) : null
}
</>
)
}Reactive options
Wrap changing options in accessors so useFloating() can track them:
import { createSignal } from '@fictjs/runtime/advanced'
import { offset, useFloating } from '@fictjs/floating-ui-dom'
function Tooltip() {
const gap = createSignal(8)
const floating = useFloating({
placement: () => 'right',
middleware: () => [offset(gap())],
})
return (
<>
<button ref={floating.refs.setReference}>Anchor</button>
<div ref={floating.refs.setFloating} style={floating.floatingStyles}>
Distance: {() => gap()}
</div>
</>
)
}The following options are reactive when provided as accessors:
openplacementstrategymiddlewareplatformtransformelements.referenceelements.floating
API
useFloating(options)arrow(options, deps?)offset(options, deps?)shift(options, deps?)limitShift(options, deps?)flip(options, deps?)size(options, deps?)autoPlacement(options, deps?)hide(options, deps?)inline(options, deps?)autoUpdatecomputePositiondetectOverflowgetOverflowAncestorsplatform
useFloating options
open: accessor-friendly boolean used to keepisPositioned()in sync with visibilityplacement: placement or accessor returning a placementstrategy: positioning strategy or accessor returning onemiddleware: middleware array or accessor returning oneplatform: custom@floating-ui/domplatform or accessor returning onetransform: whether to position with CSS transforms instead oftop/leftwhileElementsMounted(reference, floating, update): mount hook forautoUpdateelements.reference: external element, ref-like object, or accessor returning oneelements.floating: external element, ref-like object, or accessor returning one
useFloating return value
useFloating() returns:
x(),y(),strategy(),placement(),middlewareData(),isPositioned()floatingStyles, a live style object that can be passed directly tostyle={...}update(), for imperative recomputationrefs.reference,refs.floating,refs.setReference,refs.setFloatingelements.reference,elements.floating
Compatibility Notes
- Middleware helpers keep the same names and core option shapes as
@floating-ui/react-dom. - Fict does not rerender components after mount, so changing options must happen through accessors.
refs.referenceis typed asElement | VirtualElementby default, matching upstream flexibility.arrow()accepts raw DOM elements, ref-like objects, and accessors that resolve to either form.
Testing Coverage
The package test suite covers the Fict equivalents of the upstream react-dom cases, including:
- middleware freshness and update-loop safety
whileElementsMountedmount and cleanup behavior- unstable callback-ref wrappers
isPositioned()transitions across open and close cycles- internal refs and external element sources
- transform and layout-based positioning styles
- type-level coverage for generic reference narrowing and middleware typing
Differences from @floating-ui/react-dom
- dynamic configuration is driven by accessors instead of rerendering props
- returned state is accessor-based, except
floatingStyles, which is kept as a mutable style object for JSX compatibility arrow()accepts Fict refs and accessors in addition to raw DOM elements
License
MIT
