/** * Keeps the conversation pinned to the newest message while the reader is at * the bottom, and gets out of the way the moment they scroll up. * * Two things follow from that rule. A reply arriving while the reader is up in * the history must not yank them down — it raises the "jump to latest" button * instead. And their own message always scrolls into view, because they just * pressed send and expect to see it. * * @implements {ReactiveController} */ export class ScrollController implements ReactiveController { /** * @param {LitElement & { messages: Message[] }} host * @param {{ behavior: () => 'smooth' | 'instant' }} options */ constructor(host: LitElement & { messages: Message[]; }, { behavior }: { behavior: () => "smooth" | "instant"; }); /** @returns {boolean} True when newer content arrived while scrolled up. */ get hasUnseen(): boolean; /** @returns {boolean} */ get atBottom(): boolean; hostDisconnected(): void; /** * Runs before the render, so a decision made here lands in the same frame. * Whether the conversation grew is knowable from the array alone; only the * scrolling itself has to wait for the DOM. */ hostUpdate(): void; hostUpdated(): void; /** * @param {{ smooth?: boolean }} [options] Defaults to the theme's setting. */ scrollToBottom({ smooth }?: { smooth?: boolean; }): void; #private; } import type { ReactiveController } from 'lit'; import type { LitElement } from 'lit'; import type { Message } from '../types.js';