{"version":3,"file":"useComposerState-DmD2tAGF.cjs","names":[],"sources":["../src/hooks/useScrollToBottom.ts","../src/hooks/useComposerState.ts"],"sourcesContent":["\"use client\";\n\nimport { RefObject, useCallback, useEffect, useRef } from \"react\";\n\nexport type ScrollVariant = \"always\" | \"once\" | \"user-message-anchor\";\nexport const useScrollToBottom = <T extends HTMLElement | null, L extends { id: string }>({\n  ref,\n  lastMessage,\n  scrollVariant,\n  userMessageSelector = \".openui-shell-thread-message-user\",\n  isRunning,\n  isLoadingMessages,\n}: {\n  ref: RefObject<T>;\n  // scroll to bottom when this value changes\n  lastMessage: L;\n  scrollVariant: ScrollVariant;\n  userMessageSelector?: string;\n  // if true, scroll to bottom logic will work\n  isRunning?: boolean;\n  isLoadingMessages?: boolean;\n}) => {\n  const previousLastMessage = useRef<L | null>(null);\n  const lastUserMessage = useRef<HTMLElement | null>(null);\n  const hasUserScrolledWhenIsRunning = useRef(false);\n  const wasScrolledToBottomAfterLoading = useRef(false);\n\n  useEffect(() => {\n    const element = ref.current;\n    if (!isRunning || !element) {\n      hasUserScrolledWhenIsRunning.current = false;\n      return;\n    }\n    let isUserScrolling = false;\n\n    const userScrollingDisabler = () => {\n      isUserScrolling = false;\n    };\n\n    const userScrollingEnabler = () => {\n      isUserScrolling = true;\n    };\n\n    const scrollListener = () => {\n      if (!isUserScrolling) {\n        return;\n      }\n      hasUserScrolledWhenIsRunning.current = true;\n      removeListeners();\n    };\n\n    const addListeners = () => {\n      element.addEventListener(\"scroll\", scrollListener);\n      element.addEventListener(\"click\", userScrollingDisabler);\n      element.addEventListener(\"touchmove\", userScrollingEnabler);\n      element.addEventListener(\"wheel\", userScrollingEnabler);\n      element.addEventListener(\"keydown\", userScrollingEnabler);\n      element.addEventListener(\"mousedown\", userScrollingEnabler);\n    };\n\n    const removeListeners = () => {\n      element.removeEventListener(\"scroll\", scrollListener);\n      element.removeEventListener(\"click\", userScrollingDisabler);\n      element.removeEventListener(\"touchmove\", userScrollingEnabler);\n      element.removeEventListener(\"wheel\", userScrollingEnabler);\n      element.removeEventListener(\"keydown\", userScrollingEnabler);\n      element.removeEventListener(\"mousedown\", userScrollingEnabler);\n    };\n\n    addListeners();\n\n    return () => {\n      removeListeners();\n    };\n  }, [isRunning]);\n\n  const scrollToBottom = useCallback(() => {\n    const element = ref.current;\n    if (!element) {\n      return;\n    }\n\n    if (scrollVariant === \"always\") {\n      if (previousLastMessage.current !== lastMessage) {\n        const scrollBy = element.scrollHeight - element.scrollTop - element.clientHeight;\n        if (scrollBy > 90) {\n          element.scrollTo({\n            top: element.scrollHeight,\n            behavior: \"smooth\",\n          });\n        } else {\n          element.scrollTop = element.scrollHeight;\n        }\n      }\n    } else if (scrollVariant === \"once\") {\n      if (previousLastMessage.current?.id !== lastMessage.id) {\n        element.scrollTo({\n          top: element.scrollHeight,\n          behavior: \"smooth\",\n        });\n      }\n    } else {\n      const lastUserMessageDiv = Array.from(element.querySelectorAll(userMessageSelector)).pop() as\n        | HTMLElement\n        | undefined;\n      const lastUserMessageNextSibling = lastUserMessageDiv?.nextElementSibling;\n      if (\n        lastUserMessageDiv &&\n        (!lastUserMessageNextSibling?.nextElementSibling ||\n          !wasScrolledToBottomAfterLoading.current) &&\n        previousLastMessage.current?.id !== lastMessage.id\n      ) {\n        const scrollPaddingTop =\n          Number.parseFloat(window.getComputedStyle(element).scrollPaddingTop || \"0\") || 0;\n\n        // scroll to last user message till there is only 1 more message\n        const scrollPosition =\n          lastUserMessageDiv.getBoundingClientRect().top -\n          element.getBoundingClientRect().top +\n          element.scrollTop -\n          scrollPaddingTop;\n\n        element.scrollTo({ top: Math.max(scrollPosition, 0), behavior: \"smooth\" });\n        lastUserMessage.current = lastUserMessageDiv;\n      }\n    }\n\n    previousLastMessage.current = lastMessage;\n  }, [ref, lastMessage, scrollVariant, userMessageSelector]);\n\n  useEffect(() => {\n    if (\n      (isRunning && !hasUserScrolledWhenIsRunning.current) || // scroll to bottom if user hasn't scrolled when isRunning is true\n      (!wasScrolledToBottomAfterLoading.current && !isLoadingMessages) // scroll to bottom once when messages are loaded\n    ) {\n      scrollToBottom();\n      wasScrolledToBottomAfterLoading.current = true;\n    }\n\n    if (isLoadingMessages) {\n      wasScrolledToBottomAfterLoading.current = false;\n    }\n  }, [scrollToBottom, isRunning, isLoadingMessages]);\n};\n","import { useState } from \"react\";\n\nexport const useComposerState = () => {\n  const [textContent, setTextContent] = useState(\"\");\n  return { textContent, setTextContent };\n};\n"],"mappings":";;;AAKA,MAAa,qBAA6E,EACxF,KACA,aACA,eACA,sBAAsB,qCACtB,WACA,wBAUI;CACJ,MAAM,uBAAA,GAAA,MAAA,QAAuC,KAAK;CAClD,MAAM,mBAAA,GAAA,MAAA,QAA6C,KAAK;CACxD,MAAM,gCAAA,GAAA,MAAA,QAAsC,MAAM;CAClD,MAAM,mCAAA,GAAA,MAAA,QAAyC,MAAM;AAErD,EAAA,GAAA,MAAA,iBAAgB;EACd,MAAM,UAAU,IAAI;AACpB,MAAI,CAAC,aAAa,CAAC,SAAS;AAC1B,gCAA6B,UAAU;AACvC;;EAEF,IAAI,kBAAkB;EAEtB,MAAM,8BAA8B;AAClC,qBAAkB;;EAGpB,MAAM,6BAA6B;AACjC,qBAAkB;;EAGpB,MAAM,uBAAuB;AAC3B,OAAI,CAAC,gBACH;AAEF,gCAA6B,UAAU;AACvC,oBAAiB;;EAGnB,MAAM,qBAAqB;AACzB,WAAQ,iBAAiB,UAAU,eAAe;AAClD,WAAQ,iBAAiB,SAAS,sBAAsB;AACxD,WAAQ,iBAAiB,aAAa,qBAAqB;AAC3D,WAAQ,iBAAiB,SAAS,qBAAqB;AACvD,WAAQ,iBAAiB,WAAW,qBAAqB;AACzD,WAAQ,iBAAiB,aAAa,qBAAqB;;EAG7D,MAAM,wBAAwB;AAC5B,WAAQ,oBAAoB,UAAU,eAAe;AACrD,WAAQ,oBAAoB,SAAS,sBAAsB;AAC3D,WAAQ,oBAAoB,aAAa,qBAAqB;AAC9D,WAAQ,oBAAoB,SAAS,qBAAqB;AAC1D,WAAQ,oBAAoB,WAAW,qBAAqB;AAC5D,WAAQ,oBAAoB,aAAa,qBAAqB;;AAGhE,gBAAc;AAEd,eAAa;AACX,oBAAiB;;IAElB,CAAC,UAAU,CAAC;CAEf,MAAM,kBAAA,GAAA,MAAA,mBAAmC;EACvC,MAAM,UAAU,IAAI;AACpB,MAAI,CAAC,QACH;AAGF,MAAI,kBAAkB;OAChB,oBAAoB,YAAY,YAElC,KADiB,QAAQ,eAAe,QAAQ,YAAY,QAAQ,eACrD,GACb,SAAQ,SAAS;IACf,KAAK,QAAQ;IACb,UAAU;IACX,CAAC;OAEF,SAAQ,YAAY,QAAQ;aAGvB,kBAAkB;OACvB,oBAAoB,SAAS,OAAO,YAAY,GAClD,SAAQ,SAAS;IACf,KAAK,QAAQ;IACb,UAAU;IACX,CAAC;SAEC;GACL,MAAM,qBAAqB,MAAM,KAAK,QAAQ,iBAAiB,oBAAoB,CAAC,CAAC,KAAK;GAG1F,MAAM,6BAA6B,oBAAoB;AACvD,OACE,uBACC,CAAC,4BAA4B,sBAC5B,CAAC,gCAAgC,YACnC,oBAAoB,SAAS,OAAO,YAAY,IAChD;IACA,MAAM,mBACJ,OAAO,WAAW,OAAO,iBAAiB,QAAQ,CAAC,oBAAoB,IAAI,IAAI;IAGjF,MAAM,iBACJ,mBAAmB,uBAAuB,CAAC,MAC3C,QAAQ,uBAAuB,CAAC,MAChC,QAAQ,YACR;AAEF,YAAQ,SAAS;KAAE,KAAK,KAAK,IAAI,gBAAgB,EAAE;KAAE,UAAU;KAAU,CAAC;AAC1E,oBAAgB,UAAU;;;AAI9B,sBAAoB,UAAU;IAC7B;EAAC;EAAK;EAAa;EAAe;EAAoB,CAAC;AAE1D,EAAA,GAAA,MAAA,iBAAgB;AACd,MACG,aAAa,CAAC,6BAA6B,WAC3C,CAAC,gCAAgC,WAAW,CAAC,mBAC9C;AACA,mBAAgB;AAChB,mCAAgC,UAAU;;AAG5C,MAAI,kBACF,iCAAgC,UAAU;IAE3C;EAAC;EAAgB;EAAW;EAAkB,CAAC;;;;AC5IpD,MAAa,yBAAyB;CACpC,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,UAA2B,GAAG;AAClD,QAAO;EAAE;EAAa;EAAgB"}