zebflow 0.7.9

Reactive web automation platform — pipelines, templates, and real-time collaboration in a single binary.
Documentation
import { cx } from "zeb";
import { useState, useRef } from "zeb";

interface HoverCardProps {
  openDelay?: number;
  closeDelay?: number;
  children?: any;
  [key: string]: any;
}

export function HoverCard({ openDelay = 700, closeDelay = 300, children }: HoverCardProps) {
  const [isOpen, setIsOpen] = useState(false);
  const openTimer = useRef<any>(null);
  const closeTimer = useRef<any>(null);

  const handleOpen = () => {
    clearTimeout(closeTimer.current);
    openTimer.current = setTimeout(() => setIsOpen(true), openDelay);
  };

  const handleClose = () => {
    clearTimeout(openTimer.current);
    closeTimer.current = setTimeout(() => setIsOpen(false), closeDelay);
  };

  const items = Array.isArray(children) ? children : [children];
  const enhanced = items.map((child: any) => {
    if (!child || typeof child !== "object") return child;
    return { ...child, props: { ...child.props, _isOpen: isOpen, _onMouseEnter: handleOpen, _onMouseLeave: handleClose } };
  });

  return <>{enhanced}</>;
}

export function HoverCardTrigger({ children, _onMouseEnter, _onMouseLeave, asChild, className, ...rest }: any) {
  if (asChild && children && typeof children === "object") {
    return { ...children, props: { ...children.props, onMouseEnter: _onMouseEnter, onMouseLeave: _onMouseLeave } };
  }
  return (
    <span onMouseEnter={_onMouseEnter} onMouseLeave={_onMouseLeave} className={cx("inline-block", className)} {...rest}>
      {children}
    </span>
  );
}

export function HoverCardContent({ className, children, _isOpen, _onMouseEnter, _onMouseLeave, align = "center", sideOffset = 4, ...rest }: any) {
  if (!_isOpen) return null;
  return (
    <div
      role="tooltip"
      onMouseEnter={_onMouseEnter}
      onMouseLeave={_onMouseLeave}
      className={cx(
        "absolute z-50 w-64 rounded-md border border-gray-200 bg-white p-4 shadow-md outline-none",
        className
      )}
      style={{ top: "100%", marginTop: `${sideOffset}px`, left: align === "start" ? 0 : align === "end" ? "auto" : "50%", right: align === "end" ? 0 : "auto", transform: align === "center" ? "translateX(-50%)" : "none" }}
      {...rest}
    >
      {children}
    </div>
  );
}

export default HoverCard;