PettyUI/packages/core/tests/primitives/create-floating.test.tsx
Mats Bosson c78a8832d9 Floating positioning primitive
Reactive wrapper around @floating-ui/dom that auto-updates floating
element position relative to an anchor. Exports createFloating,
CreateFloatingOptions, and FloatingState from primitives index.
2026-03-29 10:25:38 +07:00

52 lines
1.6 KiB
TypeScript

import { createSignal } from "solid-js";
import { render } from "@solidjs/testing-library";
import { describe, expect, it } from "vitest";
import { createFloating } from "../../src/primitives/create-floating";
import type { CreateFloatingOptions } from "../../src/primitives/create-floating";
type PartialOpts = Partial<Pick<CreateFloatingOptions, "placement" | "strategy" | "open">>;
function renderFloating(extra: PartialOpts = {}) {
let state: ReturnType<typeof createFloating> | undefined;
render(() => {
const [anchor, setAnchor] = createSignal<HTMLElement | null>(null);
const [floating, setFloating] = createSignal<HTMLElement | null>(null);
state = createFloating({ anchor, floating, ...extra });
return (
<div>
<button ref={setAnchor}>Anchor</button>
<div ref={setFloating}>Float</div>
</div>
);
});
return state!;
}
describe("createFloating", () => {
it("returns reactive x, y, placement, and style", () => {
const state = renderFloating({ placement: () => "bottom" });
expect(typeof state.x()).toBe("number");
expect(typeof state.y()).toBe("number");
expect(state.placement()).toBe("bottom");
expect(state.style()).toHaveProperty("position");
});
it("does not compute when open is false", () => {
const state = renderFloating({ placement: () => "bottom", open: () => false });
expect(state.x()).toBe(0);
expect(state.y()).toBe(0);
});
it("style includes position strategy", () => {
const state = renderFloating({ strategy: () => "fixed" });
expect(state.style().position).toBe("fixed");
});
});