/** * Animate an element using the Web Animations API. * Returns a promise that resolves when the animation completes. * * @example * await animate(element, [ * { transform: 'scale(0.95)', opacity: 0 }, * { transform: 'scale(1)', opacity: 1 } * ]) * * @example * await animate(element, keyframes.fadeIn, { duration: 200 }) */ export declare function animate(element: HTMLElement, keyframes: Keyframe[], options?: AnimateOptions): Promise; /** * Animate elements from a previously captured layout snapshot to their current * positions. Only animations started by this helper are cancelled on later runs. */ export declare function animateFromSnapshot(snapshot: AnimationSnapshot | null, elements: Iterable, options?: AnimateFromSnapshotOptions): Animation[]; export declare interface AnimateFromSnapshotOptions extends AnimateOptions { minimumDelta?: number; includeCurrentTransform?: boolean; } export declare interface AnimateOptions { duration?: number; easing?: string | EasingName; fill?: FillMode; } export declare type AnimationSnapshot = Map; export declare type AutoScrollAxis = 'x' | 'y' | 'both'; export declare type AutoScrollContainer = Element | Window; export declare interface AutoScrollerOptions { /** Edge size in CSS pixels that starts scrolling. Defaults to 48. */ edgeThreshold?: number; /** Maximum scroll speed in CSS pixels per second. Defaults to 720. */ maxSpeed?: number; /** Limit scrolling to one axis. Defaults to both axes. */ axis?: AutoScrollAxis; /** Override scroll containers. Defaults to scrollable ancestors plus window. */ getScrollContainers?: (element: Element | null) => AutoScrollContainer[]; /** Called once per animation frame after one or more containers scrolled. */ onScroll?: () => void; } export declare function autoUpdate(reference: HTMLElement, floating: HTMLElement, update: () => void): CleanupFunction; export declare function autoUpdateTopLayerPopover(reference: HTMLElement, floating: HTMLElement, update: () => void): CleanupFunction; /** * Port of Laravel's `blank` function. * Returns true if the value is "empty" — null, undefined, empty string, empty array/object, etc. */ export declare function blank(value: unknown): boolean; /** * Cancel any running animations on an element */ export declare function cancelAnimations(element: HTMLElement): void; /** * Capture current element rectangles before a renderer changes their order or * position. Pass the snapshot to animateFromSnapshot after the DOM has updated. */ export declare function captureAnimationSnapshot(elements: Iterable): AnimationSnapshot | null; export declare type CleanupFunction = () => void; /** * Supported output formats for {@link formatColor}. */ export declare type ColorFormat = 'hex' | 'rgb' | 'hsl'; export declare function computePosition(reference: HTMLElement, floating: HTMLElement, options?: PositionOptions_2): PositionResult; /** * Create a {@link Debouncer} with a fixed delay. * * @param delay - Milliseconds to wait after the latest `schedule()` call. */ export declare function createDebouncer(delay: number): Debouncer; export declare function createFocusOutDismiss(options: FocusOutDismissOptions): FocusOutDismissController; export declare function createFocusTrap(container: HTMLElement, options?: FocusTrapOptions): CleanupFunction; export declare function createMenuNavigation(container: HTMLElement, options?: MenuNavigationOptions): CleanupFunction; export declare function createNativePopoverDisclosure(options: NativePopoverDisclosureOptions): NativePopoverDisclosureController; /** * Framework-neutral list reorder controller. It combines item registration, * live pointer preview ordering, keyboard moves, pointer commits, bounds, and * cleanup while leaving rendering, announcements, and animation policy to the * consuming package. */ export declare function createReorderableList(options: ReorderableListOptions): ReorderableListController; export declare type DarkModeStrategy = 'auto' | 'class' | 'selector' | 'media' | (() => boolean); /** * Debounce a function using requestAnimationFrame. * Ensures the function runs at most once per animation frame. * * @see https://pqina.nl/blog/applying-styles-based-on-the-user-scroll-position-with-smart-css/ */ export declare function debounce void>(fn: T): (...args: Parameters) => void; /** * A timeout-based debounced scheduler. Each `schedule()` cancels any pending * call and queues a fresh one `delay` milliseconds out. */ export declare interface Debouncer { /** Queue `fn` to run after `delay` ms, cancelling any pending call. */ schedule(fn: () => void): void; /** Cancel a pending call, if any. */ cancel(): void; } /** * Detect the browser's current framerate. * Returns a Promise that resolves with the detected FPS (capped to 30–240 range). * Falls back to 60 if requestAnimationFrame is unavailable or detection times out. */ export declare function detectFramerate(): Promise; export declare type EasingName = keyof typeof easings; /** * Tailwind CSS easing functions */ export declare const easings: { readonly linear: "linear"; readonly in: "cubic-bezier(0.4, 0, 1, 1)"; readonly out: "cubic-bezier(0, 0, 0.2, 1)"; readonly inOut: "cubic-bezier(0.4, 0, 0.2, 1)"; }; declare type ElementGetter = () => T | null; export declare interface EscapeKeyOptions { preventDefault?: boolean; stopPropagation?: boolean; } export declare function except>(target: T, keys: string[], ignoreCase?: boolean): Partial; export declare function except(target: string[], keys: string[], ignoreCase?: boolean): string[]; export declare function focusFirstEnabledElement(elements: Array): boolean; export declare interface FocusOutDismissController { markOpen: () => void; cancel: () => void; schedule: (event: FocusEvent) => void; cleanup: CleanupFunction; } export declare interface FocusOutDismissOptions { container: () => HTMLElement | null; onDismiss: () => void; delay?: number; shouldIgnore?: () => boolean; } export declare interface FocusTrapOptions { initialFocus?: boolean; initialFocusElement?: HTMLElement | null; returnFocus?: boolean; } /** * Format an alpha value as a compact decimal string (e.g. `0.5`, `1`), * dropping trailing zeros. */ export declare function formatAlpha(number: number): string; /** * Format a {@link ParsedColor} as a `hex`, `rgb`, or `hsl` string. * * By default the alpha channel is only included when the color is partially * transparent (`alpha < 1`); override with {@link FormatColorOptions.includeAlpha}. * Returned values are stable and normalized (hex is lowercase); callers may * uppercase for display. */ export declare function formatColor(color: ParsedColor, format?: ColorFormat, options?: FormatColorOptions): string; /** * Options for {@link formatColor}. */ export declare interface FormatColorOptions { /** * Whether to include the alpha channel in the output. * Defaults to `true` when the color's alpha is below 1, `false` otherwise. */ includeAlpha?: boolean; } export declare function generateId(prefix?: string): string; /** * Convert a hex color string to HSL values. * Accepts with or without leading '#'. */ export declare function hexToHsl(hex: string): HslColor; /** * Convert a hex color string to RGB channels. * Accepts any input understood by {@link parseHexColor}; falls back to black on invalid input. */ export declare function hexToRgb(hex: string): RgbColor; export declare interface HslColor { h: number; s: number; l: number; } /** * Convert HSL values to a hex color string. * h: 0-360, s: 0-100, l: 0-100 * Returns string with leading '#'. */ export declare function hslToHex(h: number, s: number, l: number): string; /** * Check whether the document is currently in RTL direction. */ export declare function isRtl(): boolean; export declare function isStandardDomEvent(eventName: string): boolean; export declare function kebabCase(string: string): string; export declare interface ListboxNavigationOptions { items: readonly T[]; currentIndex: number; key: string; isItemDisabled?: (item: T, index: number) => boolean; fallbackIndex?: number; } export declare interface ListboxNavigationResult { handled: boolean; index: number; } export declare function lockScroll(): CleanupFunction; export declare function markAriaHidden(elementOrSelector: Element | string): CleanupFunction; export declare function markInert(elementOrSelector: HTMLElement | string): CleanupFunction; export declare interface MenuNavigationOptions { itemSelector?: string; orientation?: 'vertical' | 'horizontal'; loop?: boolean; typeAhead?: boolean; onActivate?: (item: HTMLElement) => void; } export declare interface NativePopoverCloseOptions { onClose?: () => void; hide?: boolean; } export declare interface NativePopoverDisclosureController { readonly isOpen: boolean; openPopover: (options?: NativePopoverOpenOptions) => void; closePopover: (options?: NativePopoverCloseOptions) => boolean; togglePopover: (open: () => void, close: () => void) => void; showPopover: () => void; hidePopover: () => void; handlePopoverToggle: (event: Event, options?: NativePopoverToggleOptions) => boolean; handleFocusOut: (event: FocusEvent) => void; updatePosition: () => void; startAutoUpdate: () => void; cleanupPopover: CleanupFunction; } export declare interface NativePopoverDisclosureOptions { reference: ElementGetter; popover: ElementGetter; position: TopLayerPopoverPositionOptions; enabled?: () => boolean; focusOut?: FocusOutDismissOptions; onOpenChange?: (isOpen: boolean) => void; } export declare interface NativePopoverOpenOptions { onBeforeOpen?: () => void; } export declare interface NativePopoverToggleOptions { onClose?: () => void; } /** * Clamp an alpha value to the range 0-1. Non-finite input falls back to 1. */ export declare function normalizeAlpha(number: number): number; /** * Normalize a hue to an integer in the range 0-359, wrapping negatives and overflow. */ export declare function normalizeHue(number: number): number; /** * Clamp and round a percentage value to an integer in the range 0-100. */ export declare function normalizePercent(number: number): number; export declare function onceChildrenRendered(element: Element, callback: () => void): void; export declare function onClickOutside(elements: HTMLElement | HTMLElement[], callback: (event: PointerEvent) => void): CleanupFunction; export declare function onEscapeKey(callback: (event: KeyboardEvent) => void, options?: EscapeKeyOptions): CleanupFunction; export declare function only>(target: T, keys: string[], ignoreCase?: boolean): Partial; export declare function only(target: string[], keys: string[], ignoreCase?: boolean): string[]; /** * Observe changes to the document's `dir` attribute and invoke the callback * whenever it changes. Returns a cleanup function to stop observing. */ export declare function onRtlChange(callback: (rtl: boolean) => void): CleanupFunction; /** * Parse an alpha channel from a raw string as found in rgba()/hsla() notation. * * - `undefined` or empty means "no alpha specified" and returns 1 * - Percentages (`50%`) must be within 0-100 * - Decimals must be within 0-1 * - Returns `null` for out-of-range or non-numeric input */ export declare function parseAlphaChannel(rawAlpha: string | undefined): number | null; /** * Parse any supported color string (hex, rgb/rgba, hsl/hsla) into a {@link ParsedColor}. * Returns `null` for empty or unrecognized input. */ export declare function parseColorString(input: string | null | undefined): ParsedColor | null; /** * A fully normalized color model. * * - `hex` is lowercase, 6-digit, with a leading '#' * - `h` is 0-359, `s`/`l` are 0-100 * - `alpha` is 0-1 */ export declare interface ParsedColor { hex: string; h: number; s: number; l: number; alpha: number; } /** * Build a {@link ParsedColor} from a 6-digit hex string and optional alpha (0-1). */ export declare function parsedFromHex(hex: string, alphaValue?: number): ParsedColor; /** * Parse a hex color string into a {@link ParsedColor}. * * Accepts 3, 4, 6, or 8 digit hex, with or without a leading '#'. * 4/8 digit forms carry an alpha channel. Returns `null` on invalid input. */ export declare function parseHexColor(input: string): ParsedColor | null; /** * Parse an `hsl()`/`hsla()` color string into a {@link ParsedColor}. * Saturation and lightness must be percentages within 0-100. Returns `null` on invalid input. */ export declare function parseHslColor(input: string): ParsedColor | null; /** * Parse a single RGB channel from a raw string. * * - Percentages (`50%`) map 0-100 onto 0-255 * - Numbers must be within 0-255 * - Returns `null` for out-of-range or non-numeric input */ export declare function parseRgbChannel(rawChannel: string): number | null; /** * Parse an `rgb()`/`rgba()` color string into a {@link ParsedColor}. * Channels may be numeric (0-255) or percentages. Returns `null` on invalid input. */ export declare function parseRgbColor(input: string): ParsedColor | null; export declare type Placement = 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end'; declare interface PositionOptions_2 { placement?: Placement; offset?: number; flip?: boolean; /** * Constrain the floating element to the available viewport space by setting * `max-height` and `overflow-y: auto`. Mirrors the auto-sizing Headless UI * applied via its `anchor` prop, so long menus scroll instead of overflowing. */ autoSize?: boolean; } export { PositionOptions_2 as PositionOptions } export declare interface PositionResult { x: number; y: number; placement: Placement; } export declare function positionTopLayerPopover(reference: HTMLElement, floating: HTMLElement, options?: TopLayerPopoverPositionOptions): PositionResult; /** * Detect whether the user prefers dark mode. * * Strategies: * - `'class'` / `'selector'` — checks `` * - `'media'` — checks `prefers-color-scheme: dark` media query * - `'auto'` (default) — checks class first, then media query * - custom function — called directly for full control */ export declare function prefersDarkMode(strategy?: DarkModeStrategy): boolean; export declare function prefersReducedMotion(): boolean; export declare function rejectNullValues(target: T[]): Exclude[]; export declare function rejectNullValues>(target: T): Partial; /** * Attribute a caller places on a drag handle element so the pointer controller * can verify that a pointer interaction started on an actual reorder handle. */ export declare const REORDERABLE_LIST_HANDLE_ATTRIBUTE = "data-reorderable-list-handle"; export declare interface ReorderableListController { /** Register the outer list element used for default bounds and auto-scroll ancestry. */ setListElement: (element: HTMLElement | null | undefined) => void; /** Register or unregister an item element by source index. */ setItemElement: (index: number, element: HTMLElement | null | undefined) => void; /** Current registered item elements ordered by index. */ getItemElements: () => HTMLElement[]; /** Source indices in the order they should render for the live pointer preview. */ getPreviewOrder: () => number[]; /** Current items plus source and visual indices for the live pointer preview. */ getPreviewItems: () => ReorderPreviewItem[]; /** Commit an up/down keyboard reorder. */ moveItem: (index: number, direction: ReorderDirection) => ReorderMove | null; /** Begin a pointer reorder from a registered handle event. */ pointerDown: (index: number, event: PointerEvent) => void; /** Cancel active pointer work and remove global listeners. Idempotent. */ cleanup: CleanupFunction; } export declare interface ReorderableListOptions { /** Return the current ordered items. */ getItems: () => readonly T[]; /** Optional writer used by `moveItem` and pointer commits. */ setItems?: (items: T[]) => void; /** Optional guard; reordering is skipped when it returns false. Defaults to true. */ canReorder?: () => boolean; /** Optional outer collision bounds. Defaults to the registered list element rect. */ getBounds?: () => ReorderBounds | null; /** Optional edge auto-scroll while pointer-dragging. Disabled by default. */ autoScroll?: boolean | AutoScrollerOptions; /** Called whenever pointer drag state changes. */ onChange?: (state: ReorderableListState) => void; /** Called immediately before items are written or `onReorder` fires. */ onBeforeReorder?: (move: ReorderMove, context: ReorderCommitContext) => void; /** Called after a valid keyboard or pointer reorder. */ onReorder?: (move: ReorderMove, context: ReorderCommitContext) => void; } export declare type ReorderableListState = { draggedIndex: number | null; insertionIndex: number | null; targetIndex: number | null; }; export declare type ReorderBounds = { left: number; top: number; right: number; bottom: number; }; export declare type ReorderCommitContext = { /** * True when a pointer reorder already animated to the committed target * while dragging. Consumers can use this to avoid replaying the same * reorder animation on release. */ alreadyPreviewed: boolean; }; export declare type ReorderDirection = 'up' | 'down'; export declare type ReorderMove = { item: T; fromIndex: number; toIndex: number; source: ReorderSource; }; export declare type ReorderPreviewItem = { item: T; /** Index in the source item array. */ index: number; /** Index where the item is currently previewed visually. */ visualIndex: number; }; export declare type ReorderSource = 'keyboard' | 'pointer'; export declare function resolveListboxNavigation(options: ListboxNavigationOptions): ListboxNavigationResult; /** * An RGB color with 0-255 integer channels. */ export declare interface RgbColor { r: number; g: number; b: number; } /** * Convert RGB channels to a lowercase 6-digit hex string with a leading '#'. * Channels are clamped to 0-255. */ export declare function rgbToHex(r: number, g: number, b: number): string; export declare function sameUrlPath(url1: string | URL | undefined | null, url2: string | URL | undefined | null): boolean; export declare function supportsAnchorPositioning(): boolean; export declare function supportsTopLayerAnchorPositioning(): boolean; export declare function supportsWebAnimations(): boolean; export declare interface TopLayerPopoverPositionOptions { placement?: Placement; offset?: number; flip?: boolean; matchReferenceWidth?: boolean; viewportMargin?: number; anchorPositioning?: boolean; } export { }