import { onCleanup } from "solid-js";
/**
 * Class-instance-like animation-frame handle with `request` / `cancel`.
 *
 * Mirrors Base UI React's `AnimationFrame`
 * (`@base-ui/utils/useAnimationFrame` —
 * `packages/utils/src/useAnimationFrame.ts`) so component ports can read 1:1
 * against the React source.
 *
 * React's version bounces through an internal scheduler for `O(1)` cancel
 * ergonomics and fake-timer resilience; here we delegate directly to
 * `requestAnimationFrame` / `cancelAnimationFrame`. The public handle shape
 * (`request(fn)`, `cancel()`, `isStarted()`) is identical.
 */
export class AnimationFrame {
  static create() {
    return new AnimationFrame();
  }
  static request(fn) {
    return requestAnimationFrame(fn);
  }
  static cancel(id) {
    cancelAnimationFrame(id);
  }
  currentId = null;

  /**
   * Requests `fn` on the next animation frame, cancelling any previously
   * requested frame from this handle first.
   */
  request(fn) {
    this.cancel();
    this.currentId = requestAnimationFrame(() => {
      this.currentId = null;
      fn();
    });
  }
  isStarted() {
    return this.currentId !== null;
  }
  cancel = () => {
    if (this.currentId !== null) {
      cancelAnimationFrame(this.currentId);
      this.currentId = null;
    }
  };
}

/**
 * A `requestAnimationFrame` with automatic cleanup via `onCleanup`.
 *
 * Returns an {@link AnimationFrame} handle whose `request(fn)` schedules `fn`
 * on the next frame (cancelling any previously requested frame) and whose
 * `cancel()` cancels any pending frame. On disposal of the owning scope,
 * `cancel()` fires automatically so outstanding frames don't leak.
 *
 * Must be called from an owned scope so `onCleanup` has somewhere to
 * register.
 */
export function useAnimationFrame() {
  const frame = AnimationFrame.create();
  onCleanup(frame.cancel);
  return frame;
}
//# sourceMappingURL=use-animation-frame.jsx.map
