Files
vercel-labs--zerolang/docs/components/home-chat-viewport.tsx
T
wehub-resource-sync e7738de6d2
CI / Deep Native Runtime Cases (1/6) (push) Has been skipped
CI / Native Preflight (push) Failing after 1s
CI / Native Runtime Cases (1/2) (push) Failing after 0s
CI / Native Runtime Cases (2/2) (push) Failing after 1s
CI / Native Metadata Reports (push) Failing after 0s
CI / Native Direct Backend Artifacts (push) Failing after 0s
CI / Native Sanitizer Smoke (push) Failing after 1s
CI / Command Contract Snapshots (push) Failing after 1s
CI / Deep Conformance Suite (push) Has been skipped
CI / Graph Build Perf (push) Failing after 1s
CI / Deep Native Preflight (push) Has been skipped
CI / Deep Native Runtime Cases (2/6) (push) Has been skipped
CI / Deep Native Runtime Cases (3/6) (push) Has been skipped
CI / Conformance Suite (push) Failing after 1s
CI / Workspace Checks (push) Failing after 0s
CI / Deep Native Runtime Cases (5/6) (push) Has been skipped
CI / Deep Native Runtime Cases (6/6) (push) Has been skipped
CI / Deep Native Runtime Cases (4/6) (push) Has been skipped
CI / Deep Graph Build Perf (push) Has been skipped
chore: import upstream snapshot with attribution
2026-07-13 12:29:30 +08:00

58 lines
1.4 KiB
TypeScript

"use client";
import type { ReactNode } from "react";
import { useEffect, useRef, useState } from "react";
export function HomeChatViewport({ children }: { children: ReactNode }) {
const ref = useRef<HTMLDivElement>(null);
const [visible, setVisible] = useState(false);
useEffect(() => {
if (visible) {
return;
}
const element = ref.current;
if (!element) {
return;
}
const isReady = () => {
const rect = element.getBoundingClientRect();
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
const fitsInViewport = rect.height <= viewportHeight;
if (fitsInViewport) {
return rect.top >= 0 && rect.bottom <= viewportHeight;
}
return rect.top <= viewportHeight * 0.12 && rect.bottom >= viewportHeight * 0.88;
};
const update = () => {
if (!isReady()) {
return;
}
setVisible(true);
window.removeEventListener("scroll", update);
window.removeEventListener("resize", update);
};
update();
window.addEventListener("scroll", update, { passive: true });
window.addEventListener("resize", update);
return () => {
window.removeEventListener("scroll", update);
window.removeEventListener("resize", update);
};
}, [visible]);
return (
<div ref={ref} className="home-chat-viewport" data-chat-visible={visible ? "true" : "false"}>
{children}
</div>
);
}